内存 barrier/fence 如何禁止 CPU 执行的指令重新排序?
How memory barrier/fence inhibit instruction reordering carried out by CPU?
据我所知,编译器和CPU都可以进行指令重排序。
'carried out by CPU',我的意思是我不关心由编译器完成的指令重新排序以及由存储缓冲区和 CPU 缓存引起的重新排序。
对于Store Buffer和CPU Cache引起的重排序,在this论文中有讨论,我已经理解了内存屏障如何抑制这种重排序(memory reordering)。
我关心的是这样的重新排序:
源代码:
data=1; //statement1
ready=true;//statement2
但是,CPU0 上的 ThreadA 运行 按以下顺序执行上述代码:
ready=true;//statement2
data=1; //statement1
也就是说CPU对指令进行了重新排序,导致实际执行顺序与源代码指定的顺序不同。
正如我们所知,如果我们想让源代码的顺序保持不变,我们可以求助于内存屏障(或栅栏),如:
新源代码:
data=1; //statement1
smp_wb();//Insert a write barrier here!
ready=true;//statement2
所以我的问题来了:内存屏障如何在这里抑制指令重新排序?
@Tsyvarev 是正确的,它是特定于处理器(或处理器系列)的。
例如,在 ARM 下,DMB(内存屏障)导致 CPU 管道停顿以确保排序(防止重新排序),正如其 documentation 所说:
Figure 1 shows the DMB instruction being used to ensure memory
ordering by stalling the pipeline
据我所知,编译器和CPU都可以进行指令重排序。 'carried out by CPU',我的意思是我不关心由编译器完成的指令重新排序以及由存储缓冲区和 CPU 缓存引起的重新排序。 对于Store Buffer和CPU Cache引起的重排序,在this论文中有讨论,我已经理解了内存屏障如何抑制这种重排序(memory reordering)。
我关心的是这样的重新排序:
源代码:
data=1; //statement1
ready=true;//statement2
但是,CPU0 上的 ThreadA 运行 按以下顺序执行上述代码:
ready=true;//statement2
data=1; //statement1
也就是说CPU对指令进行了重新排序,导致实际执行顺序与源代码指定的顺序不同。 正如我们所知,如果我们想让源代码的顺序保持不变,我们可以求助于内存屏障(或栅栏),如:
新源代码:
data=1; //statement1
smp_wb();//Insert a write barrier here!
ready=true;//statement2
所以我的问题来了:内存屏障如何在这里抑制指令重新排序?
@Tsyvarev 是正确的,它是特定于处理器(或处理器系列)的。 例如,在 ARM 下,DMB(内存屏障)导致 CPU 管道停顿以确保排序(防止重新排序),正如其 documentation 所说:
Figure 1 shows the DMB instruction being used to ensure memory ordering by stalling the pipeline