В процессе попытки понять, как бороться с кодом, свободным от блокировки, я попытался написать одиночную свободную очередь для одного пользователя/одиночного производителя. Как всегда, я проверял бумаги, статьи и код, особенно учитывая, что это несколько деликатный вопрос.Использование std :: memory_order_consume в свободной блокировке Folly SPSC queue
Итак, я наткнулся на реализацию этой структуры данных в библиотеке Фоли, который можно найти здесь: https://github.com/facebook/folly/blob/master/folly/ProducerConsumerQueue.h
Как каждый безблокировочного очередь я видел, это один, кажется, использует циклический буфер, поэтому мы получили две переменные std::atomic<unsigned int>
: readIndex_
и writeIndex_
. readIndex_
указывают следующий индекс, по которому мы будем читать, и writeIndex_
следующий, на котором мы будем писать. Кажется достаточно простым.
Таким образом, реализация кажется чистой и довольно простой с первого взгляда, но я нашел одно неприятное. Действительно, некоторые функции, такие как isEmpty()
, isFull()
или guessSize()
, используют std::memory_order_consume
для получения значения индексов.
И, честно говоря, я действительно не знаю, какую цель они служат. Не поймите меня неправильно, я знаю об использовании std::memory_order_consume
в классическом случае переноса зависимостей через атомный указатель, но здесь мы, похоже, не несем никакой зависимости! Мы получили индексы, целые числа без знака, мы не создаем зависимости. Для меня в этом случае std::memory_order_relaxed
эквивалентен.
Однако я не верю себе, что лучше понять порядок памяти, чем те, кто разработал этот код, поэтому я задаю этот вопрос здесь. Есть ли что-то, что я пропустил или неправильно понял?
Я благодарю вас за ваши ответы!
Очень мало случаев, когда 'std :: memory_order_relaxed' действительно будет иметь значение.Вам действительно нужен чип, способный разорвать чтение/запись. Примером является x86, когда вы имеете дело с неуравновешенными данными, но вы не должны. Причина, по которой я говорю все это, заключается в том, что если вы думаете, что что-то нуждается в 'memory_order_relaxed', вы, вероятно, не понимаете использования. Вы пытаетесь предотвратить рвение чтения/записи? – SergeyA
@SideEffects: Я согласен с вами. Последующие обращения к памяти не зависят от значений индекса в этих функциях, поэтому я не вижу, как «std :: memory_order_consume» может внести что-либо полезное. Адреса авторов (авторов) находятся в верхней части файла; возможно, попробуйте отправить их по электронной почте? (Если вы это сделаете, добавьте здесь обновление или ответ. Мне любопытно, что мы чего-то не замечаем.) – Nemo
@SergeyA Да, возможно, я был здесь немного неясен. Все, что я хотел сказать, было то, что я считал, что использование памяти для заказа памяти было, по крайней мере для меня, не добавлением ничего полезного. Но, может быть, я хочу прояснить этот момент, спасибо! – SideEffects