c++ - 什么是 C++11 原子 API 等同于 `` `__asm__ volatile ("":::: "memory")`` `

标签 c++ c++11 portability atomic barrier

一个代码库有一个 COMPILER_BARRIER宏定义为 __asm__ volatile("" ::: "memory") .宏的目的是防止编译器跨屏障重新排序读写。请注意,这显然是编译器屏障,不是处理器级内存屏障。

事实上,这是相当可移植的,因为在 AssemblerTemplate 中没有实际的汇编指令,只有 volatilememory破坏。因此,只要编译器支持 GCC 的 Extended Asm 语法,它就应该可以正常工作。不过,我很好奇如果可能的话,在 C++11 原子 API 中表达这一点的正确方法是什么。

以下似乎是正确的想法:atomic_signal_fence(memory_order_acq_rel); .

我的推理是:

  • 属于 <atomic> API,仅 atomic_signal_fenceatomic_thread_fence不需要用于操作的内存地址。
  • atomic_thread_fence影响内存排序,我们不需要编译器屏障。
  • memory Extended Asm 版本中的 clobber 不区分读和写,所以看起来我们需要获取和释放语义,所以 memory_order_acq_rel似乎至少是必需的。
  • memory_order_seq_cst似乎没有必要,因为我们不需要跨线程的总顺序 - 我们只对当前线程内的指令排序感兴趣。

是否可以表达等同于__asm__ volatile("" ::: "memory")与 C++11 原子 API 完全兼容?如果是这样,是 atomic_signal_fence使用正确的 API?如果是这样,什么内存顺序参数在这里是合适的/需要的?

或者,我是不是陷入困境,有更好的方法来解决这个问题?

最佳答案

__asm__ volatile(""::::"memory") 甚至不是一个完整的编译器障碍;它只强制将加载/存储排序到其地址可能被 asm block 访问的对象,这将不包括编译器可以跟踪地址不泄漏的局部变量。例如,memset(password, 0, len); 后跟 __asm__ volatile(""::::"memory"); 可能无法将所使用的内存实际归零密码[]

这可以通过将此类对象的地址作为输入传递给 asm block 来解决,但我没有看到与 atomic_signal_fence 有任何完美的等价物。您可能做的最接近的事情是将对象的地址存储到外部链接 volatile 指针对象中(小心制作指针,而不是指向类型,volatile-qualified),然后 atomic_signal_fence 将不得不假设它可以从信号处理程序访问。

关于c++ - 什么是 C++11 原子 API 等同于 `` `__asm__ volatile ("":::: "memory")`` `,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38580321/

相关文章:

c++ - 设计访问对象所有者的元素

c++ - 递归内联函数

c++ - 我可以根据指针值从 std::list 中删除一个项目吗?

c++ - 检查枚举类是否包含特定标识符

c++ - Boost split 不遍历括号或大括号内

php - 正确的 JSON 对象标签语法

c - 使用 size_t 在 C 中检测 64 位

c++ - 三元运算符中为什么不能使用braced-init-list?

c++ - 从专门化访问模板参数

mercurial - 在闪存驱动器上运行 Mercurial?