Подтвердить что ты не робот

Как работают заборы памяти?

Мне нужно понять забор памяти в многоядерных машинах. Скажем, у меня есть этот код

Ядро 1

mov [_x], 1; mov r1, [_y]    

Core 2

mov [_y], 1; mov r2, [_x]

Теперь неожиданными результатами без забора памяти было бы то, что как r1, так и r2 могут быть 0 после выполнения. На мой взгляд, чтобы противостоять этой проблеме, мы должны поместить забор памяти в оба кода, поскольку поставить его только в один, все равно не решить проблему. Что-то вроде следующего...

Ядро 1

mov [_x], 1; memory_fence; mov r1, [_y]  

Core 2

mov [_y], 1; memory_fence; mov r2, [_x]

Насколько я понимаю, я все еще что-то пропущу? Предположим, что архитектура x86. Кроме того, может ли кто-нибудь сказать мне, как поместить забор памяти в код на С++?

4b9b3361

Ответ 1

Заборы сериализуют операцию, которую они ограждают (загружает и сохраняет), то есть никакая другая операция не может начаться до тех пор, пока забор не будет выполнен, но забор не будет выполняться до завершения всех предыдущих операций. цитирование intel делает смысл этого немного более точным (взято из инструкции MFENCE, стр. 3-628, том 2A, справочник Intel Инструкция):

Эта операция сериализации гарантирует, что каждая загрузка и сохранение инструкция, которая предшествует инструкции MFENCE в порядке выполнения программы становится видимым во всем мире перед любой инструкцией по загрузке или хранению, которая следует инструкции MFENCE.1

  • Считается, что инструкция загрузки становится глобально видимой, когда определяется значение, подлежащее загрузке в его целевой регистр.

Использование забора в С++ сложно (у С++ 11 есть семантика забора где-то, возможно, у кого-то есть информация об этом), так как это зависит от платформы и компилятора. Для x86 с использованием MSVC или ICC вы можете использовать _mm_lfence, _mm_sfence и _mm_mfence для загрузки, хранения и загрузки + сохранения фехтования (обратите внимание, что некоторые из них являются инструкциями SSE2).

Примечание: это предполагает перспективу Intel, то есть: с использованием процессора x86 (32 или 64 бит) или IA64

Ответ 2

С++ 11 (ISO/IEC 14882: 2011) определяет модель многопоточной памяти. Хотя я не знаю ни одного компилятора, который в настоящее время реализует новую модель памяти, С++ Concurrency в действии Энтони Уильямса документирует это очень хорошо. Вы можете проверить главу 5 - "Модель памяти на С++" и "Операции над атомными типами", где он объясняет, что происходит с расслабленными операциями и заборами памяти. Кроме того, он является автором библиотеки just:: thread, которая может использоваться до тех пор, пока у нас не будет поддержки поставщика компилятора нового стандарта. just:: thread является базой для библиотеки boost:: thread.