X86不提供开箱即用的顺序一致性(SC)。
X86提供TSO;因此它将免费提供以下障碍
[LoadLoad]
[LoadStore]
[StoreStore]
常规负载提供获取语义。
r1=A
[LoadLoad]
[LoadStore]
...
常规商店提供发布语义。
...
[StoreStore]
[LoadStore]
X=r1
因此,用于定期加载和存储的X86提供了获取/释放语义。
例如,这对于SC来说还不够
[StoreStore]
[StoreLoad]
X=r1
r2=Y
[LoadStore]
[LoadLoad]
在这种情况下,存储和装载仍然可以重新排序,因此不是SC。为了解决这个问题,可以添加[StoreLoad]屏障(例如MFENCE)。
[StoreStore]
[StoreLoad]
X=r1
[StoreLoad]<--
r2=Y
[LoadStore]
[LoadLoad]
所以现在我们已经从获取/发布语义升级到SC。
我的问题是关于线性化。线性化和SC之间的区别在于,使用SC时,操作的效果可以在调用开始之前或调用完成之后倾斜,但是对于线性化,要求调用的效果在调用开始和调用完成之间。
这使我产生疑问; X86可以提供线性化能力吗?
首先确定调用的开始和完成:
调用开始:发出指令;因此,当保留ROB上的条目时。
调用完成:删除ROB的指令(例如,在将商品从SB移至L1D的情况下,在商店中)。
当负载从缓存或内存中读取数据时,它将在全局范围内可见。这是在开始之后和完成之前。 MESI协议将防止负载读取过时的值。
当商店离开SB并到达L1d时,该商店将在全球范围内可见。这也在调用开始和完成之间。
所以对我来说X86可以提供线性化。
[lfence
在无序的后端中序列化执行,因此lfence
+ mfence
可以完全序列化执行+内存提交。
或使用序列化指令,例如cpuid
。英特尔在其手册中使用的技术术语是“序列化指令”,指的是在停用前一条指令之前不会开始的序列化,并耗尽存储缓冲区,然后再发布后一条指令。这就是您所说的“线性化”。 MFENCE/SFENCE/etc "serialize memory but not instruction execution"?
[How many memory barriers instructions does an x86 CPU have?列出序列化指令。