内存屏障(Memory Barrier)和内存栅栏(Memory Fence)是同一个概念,不同的叫法。
CPU两个指令:
- Store:将处理器缓存的数据刷新到内存中
- Load:将内存存储的数据拷贝到处理器的缓存中
内存屏障类型
-
LoadLoad Barriers
Load1;LoadLoad;Load2
该屏障确保Load1数据的装载先于Load2及其后所有装载指令的操作 -
StoreStore Barriers
Store1;StoreStore;Store2
该屏障确保Store1立刻刷新数据到内存(使其对其他处理器可见)的操作先于Store2及其后所有存储指令的操作 -
LoadStore Barriers
Load1;LoadStore;Store2
确保Load1的数据装载先于Store2及其后所有的存储指令刷新数据到内存的操作 -
StoreLoad Barriers
Store1;StoreLoad;Load2
该屏障确保Store1立刻刷新数据到内存的操作先于Load2及其后所有装载指令的操作。它会使该屏障之前的所有内存访问指令(存储指令和访问指令)完成之后,才执行该屏障之后的内存访问指令
StoreLoad Barriers同时具备其他三个屏障的效果,因此也称之为全能屏障(mfence)。是目前大多数处理器所支持的,但是相对其他屏障,该屏障的开销相对昂贵。
不同的CPU架构对内存屏障的实现方式与实现程度非常不一样
x86架构的内存屏障
x86架构并没有实现全部的内存屏障
Store Barrier
sfence指令实现了Store Barrier,相当于StoreStore Barriers。
强制所有在sfence指令之前的Store指令,都在该sfence指令执行前被执行,发送缓存失效信号,并把Store Buffer中的数据刷出到CPU L1 Cache中;所有在sfence指令之后的Store指令,都在该sfence指令执行之后被执行。即禁止对sfence指令前后Store指令的重排序跨越sfence指令,使所有Store Barrier之前发生的内存更新都是可见的
Load Barrier
lfence指令实现了Load Barrier,相当于LoadLoad Barriers。
强制所有在lfence指令之后的Load指令,都在该lfence指令执行之后被执行,并且一直等到Load Buffer被该CPU读完才能执行之后的Load指令(发现缓存失效后发起的刷入)。即禁止对lfence指令前后Load指令的重排序跨越lfence指令,配合Store Barrier,使所有Store Barrier之前发生的内存更新,对Load Barrier之后的Load操作都是可见的
Full Barrier
mfence指令实现了Full Barrier,相当于StoreLoad Barriers。
mfence指令综合了sfence指令与lfence指令的作用,强制所有在mfence指令之前的Store/Load指令,都在该mfence指令执行之前被执行;所有在mfence指令之后的Store/Load指令都在该mfence指令执行之后被执行。即禁止对mfence指令前后Store/Load指令的重排序跨越mfence指令,使所有Full Barrier之前发生的操作,对所有Full Barrier之后的操作都是可见的
网友评论