记忆围栏如何工作?

Met*_*est 24 c parallel-processing assembly multicore microprocessors

我需要了解多核机器中的内存屏障.说我有这个代码

核心1

mov [_x], 1; mov r1, [_y]    
Run Code Online (Sandbox Code Playgroud)

核心2

mov [_y], 1; mov r2, [_x]
Run Code Online (Sandbox Code Playgroud)

现在没有内存栅栏的意外结果是r1和r2在执行后都可以为0.在我看来,为了解决这个问题,我们应该在两个代码中都放置内存栅栏,因为将它放到一个代码中仍然无法解决问题.如下......

核心1

mov [_x], 1; memory_fence; mov r1, [_y]  
Run Code Online (Sandbox Code Playgroud)

核心2

mov [_y], 1; memory_fence; mov r2, [_x]
Run Code Online (Sandbox Code Playgroud)

我的理解是正确的还是我仍然缺少某些东西?假设架构是x86.另外,有人可以告诉我如何在C++代码中放置内存栅栏吗?

Nec*_*lis 14

Fences序列化它们围栅(加载和存储)的操作,也就是说,在执行栅栏之前不会启动任何其他操作,但是在所有前面的操作完成之前栅栏将不会执行.引用intel使其含义更加精确(取自MFENCE指令,第3-628页,第2A卷,英特尔指令参考):

此序列化操作保证在程序顺序中的MFENCE指令之前的每个加载和存储指令在遵循MFENCE指令的任何加载或存储指令之前变为全局可见.

  1. 当确定要加载到其目的地寄存器中的值时,认为加载指令变为全局可见.

在C++中使用fences是很棘手的(C++ 11可能在某处有栅栏语义,也许其他人有信息),因为它依赖于平台和编译器.对于使用MSVC或ICC的x86,您可以使用_mm_lfence,_mm_sfence&_mm_mfence用于加载,存储和加载+存储防护(请注意其中一些是SSE2指令).

注意:这假设是英特尔的观点,即:使用x86(32或64位)或IA64处理器

  • @osgx:从2011年5月起,订货号为325383-039US,以防您需要订购副本:P (2认同)