Как я могу испытать "LFENCE или SFENCE не может пройти ранее чтение / запись" - PullRequest
2 голосов
/ 21 июня 2019

Я делаю кое-что о безопасности функций.Мне нужно проверить некоторые инструкции процессора X86, такие как LFENCE, SFENCE и MFENCE.

Теперь я могу испытать MFENCE в соответствии с главой 8.2.3.4 Intel SDM «нагрузки могут быть переупорядочены с более ранним хранением в другое место».

"xor %0, %0\n\t                 "
"movl $1, %1\n\t                "
"mfence\n\t                     "   
"movl %2, %0\n\t                "
: "=r"(r1), "=m" (X)             
: "m"(Y)                         
: "memory"); 
"xor %0, %0\n\t                 "
"movl $1, %1\n\t                "
"mfence\n\t                     "   
"movl %2, %0\n\t                "
: "=r"(r2), "=m" (Y)
: "m"(X)
: "memory");

При использовании только кода выше MFENCE может предотвратить переупорядочение памяти (обнаружение различных значений r1 и r2 до / после удаления mfence в обоих процессорах)

Так что мне интересноКак я могу проверить LFENCE и SFENCE, как указано выше.Я не нашел никакой логики в SDM.

1 Ответ

3 голосов
/ 21 июня 2019

Похожие: Делает ли модель памяти Intel избыточность SFENCE и LFENCE?

sfence не имеет реального эффекта, если вы не используете магазины NT 1 . Если вы храните NT-данные, а затем указатель на эти данные (или «готовый» флаг), читатель может увидеть старое значение для данных, даже если он увидит новое значение указателя / флага. sfence может использоваться для обеспечения возможности наблюдения двух хранилищ в программном порядке.

lfence бесполезен для упорядочения памяти, если вы не выполняете загрузку NT из области памяти WC (например, видеопамяти). Вам будет очень тяжело создать случай, когда его комментирование создает различимый в порядке упорядочения памяти .

Основное использование для lfence заключается в сериализации выполнения , а не памяти. См. Понимание влияния lfence на цикл с двумя длинными цепочками зависимостей, для увеличения длины


Поскольку вы спрашивали о C, а не только об asm, есть связанный ответ о том, когда вам следует использовать _mm_sfence() и другие встроенные функции . Когда мне следует использовать _mm_sfence _mm_lfence и _mm_mfence (обычно вам действительно нужно только asm("" ::: "memory");, если NT-хранилища не находятся в полете, потому что блокировка переупорядочения во время компиляции дает вам упорядочение acq / rel без каких-либо инструкций барьера времени выполнения.)


Сноска 1: Это верно для обычных ББ (WriteBack) Настройки кэширования памяти. В пользовательском пространстве под обычной ОС это всегда так, если только вы не сделали что-то особенное.

Для других типов памяти (настройки MTRR или PAT): хранилища NT в не кэшируемой памяти не имеют специального эффекта и по-прежнему строго упорядочены. Хранилища NT в памяти WC, WB или WT (или обычные хранилища в памяти WC) упорядочены слабо, поэтому полезно использовать sfence перед сохранением флага buffer_ready для другого потока.

SSE4.1 movntdqa загрузки из памяти WB не слабо упорядочены. В отличие от магазинов, он не отменяет семантику упорядочения типов памяти. На современных процессорах ничего особенного не происходит в памяти WB; они просто менее эффективны. Используйте их только в памяти WC.

...