Я написал некоторый код без блокировки, который прекрасно работает с локальными операциями чтения при большинстве условий.
Обязательно ли при локальном вращении при чтении в памяти я должен ВСЕГДА вставлять барьер памяти перед вращением при чтении?
(Чтобы проверить это, мне удалось создать комбинацию чтения / записи, которая приводит к тому, что читатель никогда не видит записанное значение при определенных весьма специфических условиях - выделенный ЦП, процесс, подключенный к ЦП, оптимизатор повернут полностьювверх, никакой другой работы в цикле не делается - поэтому стрелки указывают в этом направлении, но я не совсем уверен в стоимости вращения через барьер памяти.)
Какова стоимость вращениячерез барьер памяти, если нечего очищать в буфере хранилища кеша?т. е. весь процесс, выполняемый (в 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:
Я проверил, что если пишущий явно не выталкивает запись из буфера хранилищаи это единственный процесс, работающий на этом процессоре, читатель может никогда не увидеть эффект писателя (я могу воспроизвести его с помощью тестовой программы, но, как я уже упоминал выше, это происходит только сc тестирование с конкретными опциями компиляции и выделенными назначениями ядра - мой алгоритм работает нормально, только когда мне стало интересно, как это работает, и я написал явный тест, который я понял, что потенциально он может иметь проблемы в будущем).
Я думаю, что по умолчанию простые записи - это записи WB (Write Back), что означает, что они не сбрасываются немедленно, но чтения принимают свое последнее значение (я думаю, они называют это «пересылкой из хранилища»).Поэтому я использую инструкцию CAS для писателя.Я обнаружил в руководстве Intel все эти различные типы реализаций записи (UC, WC, WT, WB, WP), Intel vol. 3A, глава 11-10, все еще узнавая о них.
Моя неопределенность остается за читателем.сторона: я понимаю из статьи Маккенни, что есть также очередь недействительности, очередь входящих недействительных сообщений из шины в кэш.Я не уверен, как эта часть работает.В частности, вы, похоже, подразумеваете, что цикл через обычное чтение (то есть без блокировки, без барьера и использование volatile только для того, чтобы оптимизатор оставил чтение после компиляции) будет каждый раз проверяться в «очереди недействительности»(если такая вещь существует).Если простое чтение недостаточно хорошо (т. Е. Может прочитать старую строку кэша, которая все еще кажется действительной в ожидании недействительной очереди (это звучит немного неуместно и для меня, но как тогда работают очереди аннулирования?)), Тогда атомарное чтение будетнеобходимо, и мой вопрос: в этом случае, это будет иметь какое-либо влияние на автобус?(Я думаю, что, вероятно, нет.)
Я все еще читаю руководство по Intel и, несмотря на большое обсуждение переадресации хранилища, я не нашел хорошего обсуждения очередей аннулирования.Я решил преобразовать свой C-код в ASM и поэкспериментировать. Я думаю, что это лучший способ понять, как это работает.