Ответ 1
В действительно сильной модели памяти, инструкции по искривлению забора не нужны. Все обращения к памяти будут выполняться по порядку, и все магазины будут отображаться во всем мире.
Необходимы блокировки памяти, потому что текущие общие архитектуры не обеспечивают сильную модель памяти - x86/x64 может, например, изменять порядок чтения по отношению к записи, (Более тщательный источник Руководство разработчика программного обеспечения для разработчиков Intel® 64 и IA-32, 8.2.2 Заказ памяти в P6 и более позднем процессоре Семьи" ). В качестве примера из gazillions Алгоритм Деккера не будет работать на x86/x64 без заборов.
Даже если JIT создает машинный код, в котором инструкции с загрузкой и хранением памяти аккуратно размещены, его усилия бесполезны, если ЦП затем переупорядочивает эти нагрузки и хранилища, что может, при условии сохранения иллюзии последовательной согласованности для текущего контекста/потока.
Риск слишком упрощения: он может помочь визуализировать нагрузки и хранилища в результате потока инструкций как громовое стадо диких животных. Когда они пересекают узкий мост (ваш процессор), вы никогда не сможете быть уверены в порядках животных, так как некоторые из них будут медленнее, быстрее, некоторые обгоняют, некоторые отстают. Если в начале - когда вы испускаете машинный код - вы разбиваете их на группы, устанавливая между ними бесконечно длинные ограждения, вы можете хотя бы убедиться, что группа A подходит к группе B.
Заборы обеспечивают упорядочение чтения и записи. Формулировка не является точной, но:
- забор магазина "ждет" для всех выдающихся операций хранения (записи) для завершения, но не влияет на нагрузки.
- загрузочный забор "ждет" для всех выдающихся операций загрузки (чтения) для завершения, но не влияет на магазины.
- полный забор "ждет" для завершения всех операций хранения и загрузки. Он имеет эффект, который читает и записывает до того, как забор будет выполнен до записи и загрузки, которые находятся на "другой стороне забора" (приходят позже, чем забор).
То, что JIT испускает для полного забора, зависит от архитектуры процессора (CPU) и того, какие гарантии памяти он обеспечивает. Поскольку JIT точно знает, на какой архитектуре он работает, он может выдавать правильные инструкции.
На моей машине x64 с .NET 4.0 RC это будет lock or
.
int a = 0;
00000000 sub rsp,28h
Thread.MemoryBarrier();
00000004 lock or dword ptr [rsp],0
Console.WriteLine(a);
00000009 mov ecx,1
0000000e call FFFFFFFFEFB45AB0
00000013 nop
00000014 add rsp,28h
00000018 ret
Руководство разработчика программного обеспечения для разработчиков Intel® 64 и IA-32 Глава 8.1.2:
-
"... заблокированные операции сериализуют все выдающиеся операции загрузки и хранения (то есть ждут их завершения)." ... "Заблокированные операции являются атомарными по отношению ко всем другим операциям памяти и всем внешне видимые события. Доступны только выбор команды и обращения к таблицам страниц заблокированные инструкции. Заблокированные инструкции могут использоваться для синхронизации данных, написанных один процессор и считывается другим процессором ".
-
Инструкции по упорядочению памяти адресованы этой конкретной потребности.
MFENCE
мог бы использоваться как полный барьер в вышеупомянутом случае (по крайней мере теоретически - для одного, заблокированные операции могут быть быстрее, для два из них могут привести к разному поведению).MFENCE
и его друзей можно найти в главе 8.2.5 "Усиление или ослабление модели памяти".
Есть еще несколько способов сериализации магазинов и загрузок, хотя они либо непрактичны, либо медленнее, чем приведенные выше методы:
-
В главе 8.3 вы найдете полные инструкции по сериализации, такие как
CPUID
. Эти сериализованные потоки команд также: "Ничто не может передавать инструкцию сериализации и инструкция сериализации не может передавать какую-либо другую инструкцию (чтение, запись, инструкция выборка или ввод-вывод). -
Если вы настроите память как сильную некэшированную (UC), она даст вам сильную модель памяти: никаких спекулятивных или выходы из-под контроля будут разрешены, и все обращения будут отображаться на шине, поэтому нет необходимости выдавать инструкцию.:) Конечно, это будет чуть медленнее, чем обычно.
...
Так что это зависит от. Если бы существовал компьютер с сильными гарантиями порядка, JIT, вероятно, ничего не испустил бы.
IA64 и другие архитектуры имеют свои собственные модели памяти - и, таким образом, гарантируют порядок памяти (или их отсутствие) - и их собственные инструкции/способы работы с хранением/загрузкой памяти.