当前位置: 首页 > 知识库问答 >
问题:

英特尔内存模型是否使SFENCE和LFENCE冗余?

欧阳玺
2023-03-14

Intel内存型号保证:

  • 门店不会与其他门店一起重新订购
  • 货物不会与其他货物一起重新订购

http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

我看到有人声称由于英特尔内存模型,SFENCE在x86-64上是多余的,但从来没有LFENCE。上述内存模型规则是否使任一指令冗余?

共有1个答案

相化
2023-03-14

没错,LFENCE和SFENCE在普通代码中没有用处,因为x86对常规存储的获取/释放语义使它们变得多余,除非您使用其他特殊指令或内存类型。

对于正常的无锁代码来说,唯一重要的栅栏是来自locked指令或慢速MFENCE的完整屏障(包括StoreLoad)。对于顺序一致性存储,首选xchg而不是movmford。加载和存储是唯一被重新排序的指令吗?因为它更快。

假设没有非时态指令,“xchg”是否包含“mfence”?(是的,即使使用NT指令,只要没有WC内存。)

杰夫·普雷辛(JeffPreshing)在Act文章中的记忆重新排序是巴托斯(Bartosz)的博文中描述的同一个案例的一个更容易阅读的描述,在这个案例中,你需要一个像MFENCE这样的存储负载屏障。只有MFENCE才能做到;不能用SFENCE LFENCE构造MFENCE。(为什么是(或不是?)SFENCE LFENCE等效于MFENCE?)

如果你在阅读了你发布的链接后有疑问,请阅读杰夫·普雷欣的其他博客帖子。他们让我对这个问题有了很好的理解虽然我认为我在DougLea的页面上发现了关于SFENCE/LFENCE的花絮,通常是不可操作的。Jeff的帖子没有考虑NT加载/存储。

相关:我应该何时使用\u mm\u sfence \u mm\u lfence和\u mm\u mfence(我的答案和@BeeOnRope的答案都很好。我写这个答案的时间比那个答案早得多,所以这个答案的一部分显示了我多年前的经验不足。我的答案考虑了C内部函数和C编译时内存顺序,这与x86 asm运行时内存顺序完全不同。但你仍然不想要

SFENCE仅在使用movnt(非临时)流式存储或使用类型设置为正常写回以外的内存区域时才相关。或者使用clflushope,这有点像弱有序存储。NT存储绕过缓存并且被弱排序。x86的普通内存模型是强有序的,而不是NT存储、WC(写入组合)内存和ERMSB字符串操作(见下文))。

LFENCE仅对具有弱有序加载的内存排序有用,这种情况非常罕见。(或可在NT存储之前使用常规负载订购LoadStore?)

来自WB内存的NT加载(movntdqa)仍然是强有序的,即使在假设的未来CPU上不会忽略NT提示;在x86上执行弱有序加载的唯一方法是从弱有序内存(WC)读取时,然后我认为只有使用movntdqa。这在“正常”程序中不会意外发生,所以您只有在映射视频RAM或其他东西时才需要担心这一点。

lford的主要用例根本不是内存排序,而是用于序列化指令执行,例如用于Spectre缓解或使用RDTSC。请参阅LFENCE是否在AMD处理器上序列化?以及该问题的“链接问题”侧边栏。)

几周前,我对此感到好奇,并对最近的一个问题发布了一个相当详细的答案:原子操作,std::Atomic

如果您是用C编写的,请使用std::atomic

在ARM或PPC或带有movnt的x86等弱有序架构上,您需要在写入缓冲区和设置标志以指示数据准备就绪之间执行StoreStore屏障指令。此外,读取器需要在检查标志和读取缓冲区之间执行LoadLoad屏障指令。

不算movnt,x86已经在每个负载之间设置了负载屏障,并且在每个存储之间设置了StoreStore屏障。(还保证LoadStore订购)<代码>MFENCE是所有4种屏障,包括StoreLoad,这是x86默认情况下唯一没有的屏障。MFENCE确保加载不会使用其他线程看到您的存储之前的旧预取值,并且可能会使用它们自己的存储。(同时也是NT商店订购和负载订购的障碍。)

有趣的事实:x86锁定-前缀指令也是完全的内存屏障。它们可以在旧的32位代码中替代MFENCE,这些代码可能在不支持MFENCE的CPU上运行<代码>锁添加[esp],否则0是不可操作的,并且在一级缓存中很可能很热并且已经处于MESI一致性协议的M状态的内存上执行读/修改/写周期。

SFENCE是一个商店壁垒。在NT存储之后,为后续存储创建发布语义非常有用。

LFENCE几乎总是与内存屏障无关,因为只有弱有序的负载

LoadLoad和LoadStore屏障。(loadNT/LFENCE/store NT防止存储在加载前全局可见。我认为如果加载地址是长依赖链的结果,或者是缓存中丢失的另一个加载的结果,这在实践中可能会发生。)

有趣的事实#2(感谢EOF):来自ERMSB的存储(在IvyBridge和更高版本上增强的rep movsb)是弱有序的(但不是缓存绕过)。ERMSB基于常规的快速字符串操作(自PPro以来一直存在的rep stos/movsb的微码实现的广泛存储)。

Intel在其《软件开发人员手册》第1卷第7.3.9.3节中记录了ERMSB存储“可能看起来执行不正常”的事实。他们还说

“订单相关代码应在任何字符串操作后写入离散信号量变量,以允许所有处理器看到正确排序的数据”

它们没有提到在rep movsb和存储到data\u ready标志之间需要的任何屏障指令。

按照我的理解,在rep stosb/rep movsb之后有一个隐含的SFENCE(至少是字符串数据的Geofence,可能不是其他正在运行的弱顺序NT存储)。无论如何,这个措辞意味着在所有字符串move写入之后,对标志/信号量的写入将变得全局可见,因此在用快速字符串op填充缓冲区然后写入标志的代码中,或者在读取标志的代码中,都不需要SFENCE/LFENCE。

(加载顺序总是发生的,因此您总是按照其他CPU使其全局可见的顺序来查看数据。即,使用弱顺序存储写入缓冲区不会改变其他线程中的加载仍然是强顺序的事实。)

摘要:使用普通存储写入一个标志,指示缓冲区已准备就绪。不要让读者只检查使用memset/memcpy写入的块的最后一个字节。

我还认为ERMSB存储区会阻止任何后续存储区传递它们,因此,如果您使用的是movNT,则仍然只需要SFENCE。i、 e.rep stosb作为一个整体具有发布语义wrt。早期说明。

有一个MSR位可以清除以禁用ERMSB,这有利于需要运行旧二进制文件的新服务器,旧二进制文件作为rep stosb或rep movsb的一部分写入“数据就绪”标志。(在这种情况下,我猜您得到的是旧的快速字符串微码,它可能使用高效的缓存协议,但确实会使所有存储按顺序显示给其他内核)。

 类似资料:
  • 似乎获得和释放语义学的公认定义是这样的:(引用自http://msdn.microsoft.com/en-us/library/windows/hardware/ff540496(v=vs.85). aspx) 如果其他处理器总是在任何后续操作的效果之前看到其效果,则该操作具有acquire语义。如果其他处理器在操作本身的效果之前看到前面每个操作的效果,则操作具有释放语义。 我简单地读过关于半记忆

  • 问题内容: 从我读到的内容来看,它用于修复CPU中的错误,而无需修改BIOS。根据我对汇编的基本知识,我知道汇编指令在内部由CPU分解为微代码,并相应地执行。但是intel以某种方式可以在系统启动和运行时进行一些更新。 有人有更多信息吗?是否有关于微码可以做什么以及如何使用的文档? 编辑:我读过维基百科的文章:没弄清楚我怎么能自己写一些,以及它有什么用。 问题答案: 在较早的时期,微代码在CPU中

  • 今天我想:好吧,即使人们对NIST SP 800-90A的RDRAND实现有很大的怀疑,它仍然是伪随机数生成器(PRNG)的硬件实现,对于非敏感应用程序来说必须足够好。所以我想在我的比赛中使用它,而不是Mersenne Twister。 因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间: 和 通过运行这两个,我得到: 所以,Mersenne Twister在我的CPU上比RD

  • 本人背景算法工程师,cv方向论文两篇,nlp实习经历。 一轮 25min 自我介绍 询问项目论文 问题:resnet架构、c++程序执行过程 反问 二轮 40min 自我介绍 询问项目论文(论文很细致,结构、损失、数据集、实验结果、创新点) 问题:Transformer架构、核心公式以及采用什么的正则化、BN和LN的区别。其实大部分是根据论文内容发散 反问 三轮HR面 25min 没有自我介绍 问

  • 我已经成功地设置了我的英特尔伽利略板(第2代)与最新的Windows IoT映像(2/12/2014)。我可以引导图像没有任何问题,telnet到它和运行'眨眼'应用程序罚款。 我试着运行“卡萨布兰卡”样本,并按照http://ms-iot.github.io/content/Casablanca.htm.当我远程登录Galileo板并尝试运行控制台应用程序时,我根本没有得到任何输出。尝试从Vis

  • 我正在使用Intel Ivy Bridge CPU,希望使用RDRAND操作码(https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide)在C#中。 如何通过C#调用此CPU指令?我在这里看到了一个从c#执行汇编代码的示例:C#