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

MS特定volatile是否阻止硬件指令重新排序

丌官昊天
2023-03-14

从文档中:

特定于Microsoft

当使用 /volatile: ms编译器选项时——默认情况下,当目标是ARM以外的架构时——编译器会生成额外的代码来维护对易失性对象的引用之间的排序,以及维护对其他全局对象的引用的排序。特别是:

  • 对易失性对象的写入(也称为易失性写入)具有发布语义学;也就是说,对全局或静态对象
    的引用发生在指令
    序列中对易失性对象的写入之前,将发生在编译的
    二进制文件中的易失性写入之前。
  • 对易失性对象的读取(也称为易失性读取)具有Acquire语义学;也就是说,在指令
    序列中的易失性内存读取之后发生的对全局或静态对象
    的引用将发生在编译后的二进制文件中的易失性读取之后。

这使得易失性对象可以用于多线程应用程序中的内存锁定和释放。

它肯定保证易失性防止编译器对编译时指令进行重新排序(因为它明确声明指令序列在编译后的二进制文件中是相同的)。

但我们都知道,也有类似硬件重新排序的事情(比如CPU能够根据自己的意愿重新排序指令)。volatile是否也能防止它?我知道同步原语(如互斥体)可以,但MS特定的volatile呢?

共有1个答案

顾俊誉
2023-03-14

有关MS特定volatile行为的MSDN文档可以追溯到VS2003。因此,在C 11中存在std::atomic之前,它已经存在了很长一段时间了。

因此,特定于MS的volatile似乎是过去实现获取/发布语义的方式。但现在它基本上已经过时了,他们留下了一个脚注,让您远离MS volatile,转而支持线程间通信的std::atomic和volatile:iso。

至于为什么他们排除ARM,微软直到最近才开始使用ARM。除了ARM之外,它们还支持x86、x64和安腾(已经死了)。

在x86和x64上,大多数加载和存储已经具有获取/释放语义(非时态存储除外)。因此,只要编译器不重新排序任何内容,处理器也不会重新排序,因此将保留获取/发布语义。volatile:ms标志告诉编译器不要重新排序任何内容,以便在x86和x64上实现获取/发布语义。

由于微软对ARM的支持相对较新,而MS特定的volatile(/volatile:MS)已经过时,取而代之的是std::atomic,因此他们可能决定放弃经典的volatile语义,而不是更新它们来在ARM上工作(考虑到缺乏硬件支持,这可能意味着在任何地方都添加内存障碍)。

*处理器仍然会执行它想要的任何重新排序,但它会保留程序的获取/释放语义学,因为这是x86/x64所要求的。(减去nt-store或clflush等特殊情况)它如何在不违反内存排序的情况下做到这一点是一个不同的话题。

 类似资料:
  • 变量res的值应等于3。但是当我打开优化时,编译器错误地重新排列了指令,并且res包含一些垃圾。一些可能的重新排序示例: 这是编译器中的错误吗?还是不允许像这样访问结构数据成员? 编辑: 我刚刚意识到之前的代码实际上有效,抱歉。但这不起作用: 当编译时不知道变量i时,编译器会错误地重新排序指令。

  • 问题内容: 我正在阅读此博客文章。 作者正在谈论在多线程环境中打破in 。 有了: 变成: 作者说,我引用: “我在这里所做的是添加一个附加读取: 哈希的第二次读取,在返回之前 。听起来很奇怪,而且不太可能发生,第一次读取可以返回正确计算出的哈希值,内存模型允许第二次读取返回0!这是允许的,因为该模型允许对操作进行广泛的重新排序。第二次读取实际上可以在代码中移动,以便处理器在第一次读取之前进行处理

  • 问题内容: 我想使用Redis从命令行,脚本,Web和电子表格中查询数据。除了电子表格,我可以找到所有其他示例的好例子……不过,我不太清楚从何处开始从MS Excel电子表格进行访问。谷歌让我失望。 请让我知道您会如何建议这样做,谢谢! 那些陌生的Redis的ps是此处描述的键值数据存储区:http : //code.google.com/p/redis/ 问题答案: 我想我用XLLoop找到了我

  • 问题内容: 我只是碰到一篇文章,声称我从未听过,也找不到其他地方。声称是从另一个线程的角度来看,可以根据构造函数内部的指令对构造函数返回的值的分配进行重新排序。换句话说,声称是在下面的代码中,另一个线程可以读取其中未设置的非空值。 这是真的? 编辑: 我认为从线程执行的角度来看,可以保证的分配与的分配具有先发生后关系。但是,这两个值都可能缓存在寄存器中,并且可能未按照最初写入的顺序将它们刷新到主存

  • 本文向大家介绍v-show指令算是重排吗?相关面试题,主要包含被问及v-show指令算是重排吗?时的应答技巧和注意事项,需要的朋友参考一下 当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,因v-show指令改变display的属性,会发生重排。

  • 我试图理解Java的关键字,关于在具有CPU缓存的多线程程序中写入易失性原子变量。 我已经阅读了一些教程和Java语言规范,特别是关于“订购前发生”的第17.4.5节。我的理解是,当一个线程将一个新值写入一个可变变量时,更新后的值必须对读取该变量的其他线程可见。对我来说,这些语义可以通过以下两种方式之一实现: > 线程可以在CPU缓存中缓存易失性变量,但对缓存中变量的写入必须立即刷新到主内存。换句