use*_*277 2 x86 assembly multithreading memory-barriers
该mfence 文件说以下内容:
对MFENCE指令之前发出的所有内存加载和存储到内存指令执行序列化操作.此序列化操作保证在遵循MFENCE指令的任何加载或存储指令之前,按程序顺序在MFENCE指令之前的每个加载和存储指令都变为全局可见.
据我所知,x86中没有fence指令可以防止非读取和非写入指令的重新排序.
现在如果我的程序只有一个线程,即使指令被重新排序,它仍然看起来好像指令正在按顺序执行.
但是,如果我的程序有多个线程,并且在其中一个线程中非读取和非写入指令被重新排序,其他线程会注意到这个重新排序(我假设答案是否定,否则会有一个fence指令停止非读取和非写入指令重新排序,或者我可能缺少某些东西)?
其他线程是否会注意到此重新排序
否,除了性能(使用硬件性能计数器进行定时或直接测量).或者微体系结构的侧通道(例如,与超线程/ SMT共享物理核心的逻辑核心的ALU端口压力):一个线程可以自行计时以了解其他硬件线程正在执行的内容.
线程观察彼此之间的唯一"正常"方式是加载其他线程存储的数据.
甚至负载排序也只是间接可见(通过它对其他线程决定稍后存储的影响).
据我所知,x86中没有fence指令可以防止非读取和非写入指令的重新排序.
在Intel CPU(但不是AMD)上,lfence这样做.英特尔手册是这么说的,这是不是只是一个实现细节.它实际上保证了未来的微体系结构.
英特尔的LFENCE指令集参考手册条目:
LFENCE不会执行,直到所有先前的指令在本地完成,并且在LFENCE完成之前没有后续指令开始执行.
(在本地完成=从无序核心退役,即离开ROB).
lfence作为实际的负载障碍并不是特别有用,因为x86不允许来自WB内存的弱有序负载(仅来自WC).(甚至没有movntdqa或prefetchnta,可以创建一个从正常WB内存弱有序负载)一点都不像sfence,lfence基本上都不需要内存排序,只为它的特效,比如 lfence; rdtsc.或者对于Spectre缓解,阻止通过它的推测性执行.
但作为一个实现细节,英特尔CPU至少包括Skylake,mfence 是乱序执行的障碍. 请参阅是否加载并存储重新排序的唯一指令?为此,以及更多相关的东西.