众所周知,PowerPC具有较弱的内存模型,该模型允许任何推测性的重新排序:存储-存储,加载-存储,存储-加载,加载-加载。
至少有3个栅栏:hwsync
或sync
-完整的内存屏障,可防止重新排序lwsync
-防止重新排序的内存屏障:加载,加载,存储,加载isync
-指令障碍:https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.alangref/idalangref_isync_ics_instrs.htm
例如,可以在此代码中对Store- stwcx.
和Load- 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)
众所周知,
isync
防止重新排序lwarx
,bne
any following instructions
。但是
isync
是否阻止对stwcx.
,bne
any following instructions
重新排序?即Store-
stwcx.
可以比以下Load- lwz
早开始,并且比Load- lwz
晚执行吗?即可以在以下Load-
stwcx.
开始之前将Store- lwz
预成型件存储到存储缓冲区中,但是对所有CPU内核可见的实际到高速缓存的实际存储发生在Load- lwz
完成之后?正如我们从以下文档,文章和书籍中看到的:
isync
不是内存屏障,而仅是指令屏障。isync
并不强制所有外部访问相对于其他访问内存的处理器和机制完成。isync
不等待所有其他处理器检测到存储访问isync
的开销非常低且非常弱(低于lwsync
和hwsync
)isync
不保证其他处理器将按照本地发出的顺序来感知以前和将来的存储-这需要同步指令之一。isync
是获取障碍,但是众所周知,获取只能应用于加载操作,而不能应用于存储(stwcx.
)isync
不会影响数据访问,也不会等待所有存储执行。最初的主要问题是:a = 0,b = 0
如果CPU-Core-0执行:
stwcx. [a]=1
bne-
isync
lwz [b]
。而CPU-Core-1则执行:
hwsync
stw [b]=1
hwsync
lwz [a]
hwsync
。然后Core-0可以看到
[b]==1
,Core-1可以看到[a]==0
吗?也:
https://www.ibm.com/developerworks/systems/articles/powerpc.html
isync阻止推测性执行访问数据块
在设置标志之前。并与前述
加载,比较和条件分支指令isync
保证分支所依赖的负载(
标志)是在
isync(从共享块加载)。
isync不是内存障碍指令,而是
负载比较条件分支isync序列可以提供此条件
订购属性。
http://www.nxp.com/assets/documents/data/en/application-notes/AN2540.pdf
与isync不同,sync会强制所有外部访问完成
关于访问内存的其他处理器和机制。
PowerPC中的存储Janice M. Stone,Robert P. Fitzgerald,1995年:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.4033&rep=rep1&type=pdf
与sync不同,isync不会等待所有其他处理器检测到
存储访问。与同步相比,isync的保守性较低
它不会延迟,直到所有处理器都检测到先前的负载并
商店。
http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2745.html
bc; isync:这是开销非常低且非常弱的内存形式
栅栏。 BC(分支)在其上的一组特定的先前荷载
有条件的)取决于指令,确保已完成
在任何后续指令开始执行之前。然而,
尽管如此,存储缓冲区和缓存状态效果仍可以使其出现
随后的负载发生在之前的负载之前,
twi指令取决于。就是说,PowerPC体系结构没有
允许以推测方式执行存储,因此遵循
twi; isync指令保证在任何加载之后发生
公元前所依赖的。
https://books.google.ru/books?id=TKOfDQAAQBAJ&pg=PA264&lpg=PA264&dq=isync+store+load&source=bl&ots=-4FyWvxTwg&sig=r1fitaG-Q3GHOxvSMTgLJMBVGUU&hl=ru&sa=X&ved=0ahUKEwiKjYK97urTAhUJ_iwKHbfMA58Q6AEIOjAC#v=onepage&q=isync%20store%20load&f=false
https://books.google.ru/books?id=gZZgAQAAQBAJ&pg=PA71&lpg=PA71&dq=isync+store+load&source=bl&ots=bo6nTLdzEZ&sig=vCjoDmUWhn0buN_uMf8XgbDzCf4&hl=ru&sa=X&ved=0ahUKEwiKjYK97urTAhUJ_iwKHbfMA58Q6AEIcTAJ#v=onepage&q=isync%20store%20load&f=false
https://books.google.ru/books?id=G2fmCgAAQBAJ&pg=PA321&lpg=PA321&dq=isync+store+load&source=bl&ots=YS4mE-4f_F&sig=OVwaJYE-SNnor-KtKrjlkOd6AOs&hl=ru&sa=X&ved=0ahUKEwiKjYK97urTAhUJ_iwKHbfMA58Q6AEIYjAH#v=onepage&q&f=false
http://www.nxp.com/assets/documents/data/en/application-notes/AN3441.pdf
请注意,isync不会影响数据访问并且不会等待
所有要执行的存储。
页面77:https://www.setphaserstostun.org/power8/POWER8_UM_v1.3_16MAR2016_pub.pdf
3.5.7.2指令缓存块无效(icbi)
作为此设计和其他特定于实现的设计的结果
优化,而不需要指定指令序列
由Power ISA在每个缓存行的基础上执行的软件
只需执行三个指令的单个序列即可
以前的代码修改可见:
sync
,icbi
(对于任何地址),
isync
。回答:
因此,
isync
不保证存储加载顺序,因为“ isync并非内存障碍指令”,因此isync
不保证其他任何CPU内核都可以看到以前的任何存储(使用顺序一致性) ),直到下一个指令完成。指令同步命令isync
仅保证启动指令的顺序,但不保证指令完成的顺序,即不保证它们对其他CPU内核可见的顺序。这些isync
允许在此代码stwcx. [a]=1; bne-; isync; lwz [b]
中重新排序Store-Load的可见效果。 最佳答案
正如您已经猜到的,并且您的绝大部分优秀资源都暗示,这里涉及到内存访问的两个属性:
能见度
其他处理器是否可以阻止内存访问。
使用特定于处理器的缓冲区或高速缓存可以使存储在处理器上完成,但对其他存储不可见。
定购
当相对于同一处理器上的其他指令执行存储器访问时。
排序是内存访问的处理器内方面,它控制处理器的乱序功能。
无法根据其他处理器的指令进行排序。
可见性是处理器间的一个方面,它确保内存访问的副作用对于其他处理器(或通常对其他代理)可见。
商店的主要副作用是更改了内存位置。
通过控制这两个方面,可以强制执行进程间排序,即其他处理器看到内存访问序列的顺序。
令人难以理解的是,除非在没有其他代理的情况下使用,否则“排序”一词通常是指第二种含义。
诚然,这是一个令人困惑的术语。
请注意,我对PowerPC架构不满意,我只是在网上找到一些官方文档以及您提供的报价的帮助下应用该理论。
就像isync
和sc
是Context-Synchronizing instructions一样,rfi
的主要目的是确保后续指令在先前指令建立的上下文中执行。
例如,执行系统调用会更改上下文,而我们不希望特权代码在非特权上下文中执行,反之亦然。
这些指令等待所有先前分派的指令完成但不可见
先前发布的所有说明均已完成,至少达到了它们无法再执行的程度
引起异常。
但是,这些指令导致的内存访问不需要
关于其他处理器和机制的完整说明。
因此,根据您所说的重新排序,isync
是否会阻止或不进行Load-Load,Load-Store等重新排序。
从执行它的处理器的角度来看,它确实防止了任何这样的重新排序(进程内重新排序)-所有先前的加载和存储在isync
完成之前就已完成,但不一定可见。
它不能确保其他指令的可见性,因此不会从其他处理器的角度阻止重新排序(进程间重新排序)。
但是,isync是否可以防止对stwcx。,bne 进行任何以下说明的重新排序?
仅在进程内重新排序。
即可以存储-stwcx。在以下Load-lwz之前开始,并在Load-lwz以后开始完成?
不是从执行它们的处理器的角度来看,在stwcx.
开始之前完成lwz
,但是使用Intel术语,它在本地完成-其他处理器可能在lwz
之前看不到它完成。开始。
即可以存储-stwcx。预先存储在以下Load-lwz开始之前存储到Store-Buffer,但是对所有CPU内核可见的实际到高速缓存的存储发生在Load-lwz完成之后?
对,就是这样。