Я написал код без блокировки, который отлично работает с локальным чтением в большинстве условий.
Обязательно ли локальное вращение при чтении памяти означает, что я должен ВСЕГДА вставлять барьер памяти перед вращением чтения?
(Чтобы проверить это, мне удалось создать комбинацию считывающего / записывающего устройства, в результате чего читатель никогда не видит записанное значение при определенных очень специфических условиях - выделенный ЦП, процесс, подключенный к ЦП, оптимизатор включен полностью, никакой другой работы выполняется в цикле - поэтому стрелки указывают в этом направлении, но я не совсем уверен в стоимости прокрутки через барьер памяти.)
Какова стоимость прокрутки через барьер памяти, если в буфер хранилища кеша нечего сбрасывать? т.е. все, что делает процесс (в C),
while ( 1 ) {
__sync_synchronize();
v = value;
if ( v != 0 ) {
... something ...
}
}
Правильно ли я предполагаю, что это бесплатно и не будет загружать шину памяти каким-либо трафиком?
Другой способ выразить это - спросить: делает ли барьер памяти что-либо большее, чем: очищает буфер хранилища, применяет к нему недействительность и не позволяет компилятору переупорядочивать операции чтения / записи по его местоположению?
Дизассемблирование, __sync_synchronize (), похоже, переводится в:
lock orl
Из мануала Intel (аналогично туманного для новичка):
Volume 3A: System Programming Guide, Part 1 -- 8.1.2
Bus Locking
Intel 64 and IA-32 processors provide a LOCK# signal that
is asserted automatically during certain critical memory
operations to lock the system bus or equivalent link.
While this output signal is asserted, requests from other
processors or bus agents for control of the bus are
blocked.
[...]
For the P6 and more recent processor families, if the
memory area being accessed is cached internally in the
processor, the LOCK# signal is generally not asserted;
instead, locking is only applied to the processor’s caches
(see Section 8.1.4, “Effects of a LOCK Operation on
Internal Processor Caches”).
Мой перевод: «когда вы говорите LOCK, это будет дорого, но мы делаем это только там, где это необходимо».
@BlankXavier:
Я проверил, что если писатель явно не выталкивает запись из буфера хранилища, и это единственный процесс, запущенный на этом ЦП, читатель может никогда не увидеть эффект писателя (я могу воспроизвести это с тестовой программой, но, как я уже упоминал выше, это происходит только с конкретным тестом, с определенными параметрами компиляции и выделенными основными назначениями - мой алгоритм работает нормально, только когда мне стало любопытно, как это работает, и я написал явный тест что я понял, что у этого потенциально могут быть проблемы в будущем).
Я думаю, что по умолчанию простая запись - это запись WB (обратная запись), что означает, что они не удаляются немедленно, но при чтении будет приниматься самое последнее значение (я думаю, они называют это «переадресацией хранилища»). Поэтому я использую инструкцию CAS для писателя. Я обнаружил в руководстве Intel все эти различные типы реализаций записи (UC, WC, WT, WB, WP), Intel vol 3A, главы 11-10, но все еще изучаю их.
Моя неуверенность на стороне читателя: я понимаю из статьи Маккенни, что существует также очередь недействительности, очередь входящих аннулирований из шины в кеш. Я не уверен, как работает эта часть. В частности, вы, кажется, подразумеваете, что цикл через нормальное чтение (то есть без блокировки, без барьера и с использованием volatile только для обеспечения того, чтобы оптимизатор оставил чтение после компиляции), каждый раз будет проверять "очередь недействительности" (если такое существует). Если простого чтения недостаточно (т. Е. Можно прочитать старую строку кеша, которая все еще остается действительной в ожидании признания недействительности в очереди (для меня это тоже звучит немного бессвязно, но как тогда работают очереди недействительности?)), Тогда атомарное чтение будет будет необходимо, и мой вопрос: в таком случае, повлияет ли это на автобус? (Думаю, наверное, нет.)
Я все еще читаю руководство Intel, и, хотя я вижу отличное обсуждение переадресации магазина, я не нашел хорошего обсуждения очередей недействительности. Я решил преобразовать свой код C в ASM и поэкспериментировать, я думаю, что это лучший способ действительно почувствовать, как это работает.