众所周知,PowerPC具有较弱的内存模型,它允许进行任何推测性的重新排序:存储-存储,加载-存储,存储-加载,加载-加载。
至少有3个栅栏:
hwsync或sync-完整的内存屏障,防止任何重新排序lwsync -防止重新排序的内存屏障:加载,加载,存储,加载isync- 指令障碍:https : //www.ibm.com/support/knowledgecenter/zh-CN/ssw_aix_71/com.ibm.aix.alangref/idalangref_isync_ics_instrs.htm例如,是否可以在此代码中重新排序“存储stwcx.和加载” lwz?:https : //godbolt.org/g/84t5jM
lwarx 9,0,10
addi 9,9,2
stwcx. 9,0,10
bne- 0,.L2
isync
lwz 9,8(1)
Run Code Online (Sandbox Code Playgroud)
如已知的,isync防止重新排序lwarx,bne< - > any following instructions。
但是是否可以isync防止重新排序stwcx.,bne<-> any following instructions?
即可以先stwcx.于以下Load-开始存储lwz,而比Load-之后执行完成lwz。
即可以stwcx.将存储库预执行的存储早于随后的加载lwz开始存储到存储缓冲区,但是对所有CPU内核可见的实际存储到高速缓存的发生要晚于加载lwz完成?
我们从以下文档,文章和书籍中看到:
isync 不是内存围栏,而仅仅是指令围栏。
isync 对于访问存储器的其他处理器和机制,并不强制完成所有外部访问。
isync 不等待所有其他处理器检测到存储访问
isync …
在C++内存模型中,所有顺序一致操作的所有加载和存储都有一个总顺序.我想知道这是如何与具有其他内存排序的操作交互,这些内存排序在顺序一致的加载之前/之后排序.
例如,考虑两个线程:
std::atomic<int> a(0);
std::atomic<int> b(0);
std::atomic<int> c(0);
//////////////
// Thread T1
//////////////
// Signal that we've started running.
a.store(1, std::memory_order_relaxed);
// If T2's store to b occurs before our load below in the total
// order on sequentially consistent operations, set flag c.
if (b.load(std::memory_order_seq_cst) == 1) {
c.store(1, std::memory_order_relaxed)
}
//////////////
// Thread T2
//////////////
// Blindly write to b.
b.store(1, std::memory_order_seq_cst)
// Has T1 set c? If so, then we know our store to b occurred before …Run Code Online (Sandbox Code Playgroud)