Paměťová bariéra ( membar , memory fence, fence instrukce ) je typ bariérové instrukce , která říká kompilátoru (při generování instrukcí) a CPU (při provádění instrukcí), aby vytvořily přísnou sekvenci mezi přístupy do paměti před a za bariérou. To znamená, že je zaručeno, že všechny přístupy do paměti před bariérou budou dokončeny před prvním přístupem do paměti za bariérou.
Paměťové bariéry jsou nezbytné, protože většina moderních procesorů používá optimalizaci výkonu, která může vést k přeskupení instrukcí . Také přeuspořádání přístupů do paměti může být způsobeno kompilátorem v procesu optimalizace využití registrů cílového procesoru. Takové permutace obvykle neovlivňují správnost programu s jedním vláknem provádění, ale mohou způsobit nepředvídatelné chování v programech s více vlákny. Pravidla pro změnu pořadí provádění instrukcí závisí na architektuře. Některé architektury poskytují více typů bariér s různými zabezpečeními. Například amd64 poskytuje následující instrukce: (SFENCE store fence ), ( load fence ), ( memory fence ) [1] . Intel Itanium poskytuje samostatné paměťové bariéry „ získání “ a „uvolnění“ ( anglicky release ) , které zohledňují viditelnost čtení po zápisech z pohledu čtenáře a zapisovače. LFENCE MFENCE
Paměťové bariéry se obvykle používají při implementaci synchronizačních primitiv , neblokujících datových struktur a ovladačů, které interagují s hardwarem .
Následující program je spuštěn na dvou procesorech.
Zpočátku paměťové buňky xa fobsahují hodnotu 0. Program v procesoru č. 1 cykluje až do fnuly, pak vypíše hodnotu x. Program v procesoru #2 zapíše hodnotu 42do xa poté uloží hodnotu 1do f. Pseudokód pro dva úryvky programu:
Procesor #1:
while ( f == 0 ) { } // Zde je potřeba bariéra print x ;Procesor #2:
x = 42 ; // Zde je potřeba bariéra f = 1 ;Ačkoli se očekává, že printvždy vytiskne „42“, pokud procesor č. 2 změní pořadí provádění instrukcí a nejprve změní hodnotu, fpak tisk může vytisknout „0“. Podobně může procesor č. 1 číst xpřed fa tisk znovu vypíše neočekávanou hodnotu. U většiny programů není žádná z těchto situací přijatelná. Před změnou hodnoty lze vložit paměťovou bariéru pro procesor #2 f. Před čtením je také možné vložit bariéru pro procesor #1 x[2] .
Paměťové bariéry fungují pouze na hardwarové úrovni. Kompilátory mohou také změnit pořadí instrukcí jako součást optimalizace programu. Opatření prevence změny pořadí jsou nezbytná pouze pro data, která nejsou chráněna synchronizačními primitivy.
V C a C++ je nestálé klíčové slovo určeno k vyloučení optimalizací kompilátoru. Nejčastěji se používá pro práci s paměťově mapovanými I/O. Toto klíčové slovo však (na rozdíl od Javy) žádným způsobem neposkytuje atomicitu a ochranu proti spuštění mimo pořadí. [3]