【问题标题】:C and C++ compilers with "aggressive" volatile semantics具有“激进”易失语义的 C 和 C++ 编译器
【发布时间】:2012-06-29 07:52:04
【问题描述】:

是否有任何 C 或 C++ 编译器为 volatile 变量实现“积极”内存一致性模型? “积极”一致性模型是指在生成的代码中伴随所有对 volatile 变量的写入以及内存屏障。

AFAIK,这是 IA64 (Itanium) 平台上 C 或 C++ 编译器的习惯行为。 x86呢?是否有编译器可以实现(或可以配置为实现)类似 Itanium 的方法来处理 x86 平台上的 volatile 变量?

编辑:我正在查看 VS 2005 生成的代码(在阅读 cmets 之后),在访问 volatile 变量时,我没有看到任何类似于任何类型的内存屏障的内容。由于 MESIF (Intel) 和 MOESI (AMD) 缓存协议,这对于确保单 CPU 多核 x86 平台上的内存一致性非常好。

但是,这在多 CPU SMP x86 平台上似乎是不够的。 SMP 平台在生成的代码中需要内存屏障,以确保 CPU 之间的内存一致性。我错过了什么?当微软声称他们已经在volatile 变量上具有获取-释放语义时,究竟是什么意思?

【问题讨论】:

  • According to Raymond Chen 你会在 VS2005 和更新版本中得到这种行为
  • @Prætorian : According to the official documentation 也是如此。 ;-]
  • @AndreyT:您是在测试 VC++ 2005 还是 VC++ 2005 SP1? IIRC, VC++ 2005 RTM 有一个错误,volatile 没有预期的语义,这在 SP1 和 VC++ 2008+ 中已修复。
  • 此说法不正确:“但是,这在多 CPU SMP x86 平台上是不够的。”无论是否全部在一个芯片中,内核的物理封装都不会改变 x86 中的软件内存排序模型,至少对于 Intel 平台是这样。

标签: c++ c x86 volatile smp


【解决方案1】:

应该注意的是,x86 CPU 既不会将加载与其他加载一起重新排序,也不会将存储与其他存储一起重新排序。因此,不需要明确的障碍。

MSVC 编译器将确保加载不会使用 volatile 加载重新排序,并且存储不会使用 volatile 存储重新排序(当然,我现在谈论的是重新排序加载和存储指令),从而保证 volatile 加载的获取和释放语义和商店。

【讨论】:

  • 即使对于多 CPU 情况也是如此(相对于单 CPU 多核情况)?
  • @AndreyT,外部总线看到加载的顺序和加载指令的顺序是一样的。商店也是如此。如您所述,缓存协议可确保一致性。换句话说,如果 CPU1 执行存储 S 并且 CPU2 看到该存储及其加载 L,那么 CPU2 在 L 之后的加载将看到 CPU1 在 S 之前的所有存储。我的朋友,这是获取/释放语义:)
  • @AndreyT,我不是要咆哮,但我希望 C++ 委员会制定“volatile 具有获取/释放语义”的保证标准,而不是提出 <atomic>
  • @avakar:我不知道。 <atomic> 提供比获取/释放更强大的保证,例如顺序一致性,而volatile 有其他用途——它应该用于线程。
  • @avakar 对于在缓存一致性较弱的设备上运行并使用 volatile 访问控制寄存器的程序来说,这是否意味着性能下降?即使它实际上并不需要它,是否也需要时间来保持缓存一致性?不混合两组语义似乎是合理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
相关资源
最近更新 更多