вопрос о блокировке свободных очередей - PullRequest
1 голос
/ 07 августа 2011

У меня есть вопрос об использовании очередей без блокировки.

Предположим, у меня есть очередь с одним потребителем для одного производителя, где производитель и потребитель связаны с отдельными ядрами.Элементы очереди - это буферы разделяемой памяти, которые вначале отображаются как производителем, так и потребителем.

Производитель получает элемент очереди, заполняет буфер данными и ставит их в очередь, а потребитель удаляет элемент из очереди,читает его и обрабатывает его некоторым образом.

Должен ли я, как пользователь очереди без блокировки, явно гарантировать, что буфер, написанный производителем, будет видим для пользователя?Или же примитив CAS (или другой подобный) в основе алгоритма автоматически обеспечивает барьер?

В парах примеров, которые я видел, используются целые числа в качестве полезной нагрузки, поэтому этот вопрос о синхронизации памяти не возникает.

Спасибо,

Ответы [ 4 ]

0 голосов
/ 12 августа 2011

Должен ли я, как пользователь очереди без блокировки, явно гарантировать, что буфер, написанный производителем, будет виден пользователю? Или примитив CAS (или другой подобный) в основе алгоритма автоматически обеспечивает барьер?

Семантически, отправка данных в параллельную очередь должна иметь, по крайней мере, ограничение на освобождение, а выталкивание из очереди должно иметь, по крайней мере, ограничение на получение. Я считаю, что хорошая реализация без блокировок не должна навязывать пользователям заботу об ограждении памяти и т. Д. Даже если алгоритм без блокировки автоматически не ставит ограждения в надлежащие места (или не для каждой архитектуры), реализация, а не пользователи, должны обеспечивать правильную видимость и порядок. Пользователи должны заботиться только о том, чтобы выбрать реализацию, которая «просто работает» (которая может / должна включать тестирование, которое действительно работает):)

0 голосов
/ 07 августа 2011

Это по определению зависит от архитектуры.Для GCC на процессорах Intel используйте GCC Atomic Builins - большинство из них подразумевают полный барьер памяти.

0 голосов
/ 09 августа 2011

Несколько архитектур связывают барьеры памяти с CAS; x86 / x64 - это один.

Другие (например, ARM) этого не делают. В ARM вы выполняете LL / SC с ручным барьером только для данных до и после.

0 голосов
/ 07 августа 2011

Блокированные примитивы, такие как сравнение и замена, обычно бывают в вариантах с различной семантикой барьера памяти.Они несколько различаются в зависимости от архитектуры, но обычно вам нужно иметь семантику «выпуска» (не позднее) операции в производителе, которая делает структуру видимой для потребителя, и что-то с семантикой «приобретения» в потребителе перед вами.получить доступ к структуре данных.

На некоторых архитектурах (в частности, vanilla x86) у вас фактически нет выбора, потому что каждая операция с блокировкой подразумевает полный барьер - но если это приведет вас кпривычка не запрашивать какой-либо барьер, из-за Мерфи будет возвращаться и кусать вас за какую-то другую архитектуру.

(И наоборот, а также из-за Мерфи, если вы тщательно исследуете вариантыи повсеместно вставляя правильные барьеры, события, вероятно, сговорются, чтобы сделать так, чтобы ни один код, который вы когда-либо пишете, не нуждался в выполнении на чем-либо, кроме x86).

...