什么是 C++11 原子 API 等同于"__asm__易失性( " " ::: "memory" )"''
What is the C++11 atomic API equivalent to ```__asm__ volatile("" ::: "memory")```
代码库有一个定义为__asm__ volatile("" ::: "memory")
的COMPILER_BARRIER
宏。宏的目的是防止编译器跨屏障重新排序读写操作。请注意,这是一个明确的编译器障碍,不是处理器级内存障碍。
事实上,这是相当可移植的,因为AssemblerTemplate中没有实际的汇编指令,只有volatile
和memory
clobber。因此,只要编译器遵守GCCs Extended Asm语法,它就应该可以正常工作。尽管如此,如果可能的话,我很好奇在C++11原子API中表达这一点的正确方式是什么。
以下似乎是正确的想法:atomic_signal_fence(memory_order_acq_rel);
。
我的理由是:
- 在
<atomic>
API中,只有atomic_signal_fence
和atomic_thread_fence
不需要针对其进行操作的内存地址 atomic_thread_fence
会影响内存排序,这对于编译器来说是不需要的- Extended Asm版本中的
memory
clobber不区分读取和写入,因此我们似乎同时想要获取和发布语义,因此似乎至少需要memory_order_acq_rel
memory_order_seq_cst
似乎没有必要,因为我们不需要跨线程的总顺序——我们只对当前线程中的指令排序感兴趣
是否可以用C++11原子API完全可移植地表达__asm__ volatile("" ::: "memory")
的等价物?如果是,那么atomic_signal_fence
是正确的API吗?如果是,那么这里需要什么样的内存顺序参数?
或者,我是不是陷入了困境,有更好的方法来解决这个问题?
__asm__ volatile("" ::: "memory")
甚至不是一个完整的编译器障碍;它只强制对asm块可能访问其地址的对象进行加载/存储排序,而asm块不包括编译器可以跟踪其地址不泄漏的局部变量。例如,后面跟有__asm__ volatile("" ::: "memory");
的memset(password, 0, len);
可能无法实际将password[]
使用的存储器归零。
这可以通过将这些对象的地址作为输入传递到asm块来弥补,但我看不到atomic_signal_fence
有任何完美的等价物。最接近的方法可能是将对象的地址存储到外部链接volatile
指针对象中(注意使指针而不是指向类型volatile
限定),然后atomic_signal_fence
必须假设它可能是从信号处理程序访问的。
区分读和写,这样看起来我们想要获取和发布语义
你似乎把不同的问题搞混了。
获取和释放语义都可以对读取和写入产生约束:
- 释放非正式地表示在屏障启动之前,先前的内存操作已经完成
- 非正式地获取意味着在屏障完成之前不会开始以下内存操作
然而,这是一个非常简单的解释C++原子屏障是原子学的屏障。它们与原子物体协同工作。当然,线程屏障调用可以自己生成代码,但可以使用一些非原子操作对代码进行重新排序。
- Python ctype 'c_char_p' Memory Leak
- 使用C++获取程序的 ASM
- 模式"allocate memory or use existing data"
- 在 c++ 中使用 x86 DIV 的这个 asm 块有什么用?
- Win32 API - HWND "{unused = ???} Unable to read memory"错误
- "in-situ without memory allocation" 字符串的愚蠢实现意味着什么?
- g++ -O3 为 loop 创建了奇怪的指令 - 两个具有相同 asm 的版本
- Extern "C"错误在'int'之前'asm'或'__attribute__'
- 了解 C/C++ 中 Windows / MSVC 的一些反调试内联 asm
- 尝试使用 x86 asm SSSE3 将大端转换为小端序
- 如何使用"asm volatile"编写 btr 指令
- C++ "Using Uninitialized Memory.. (variable name) "
- objdump 不显示机器代码,但显示 ASM
- "Memory Fragmentation"这仍然是一个问题?
- 未使用的 asm() 在不受支持的体系结构上的行为
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- std::mutex::lock() 产生奇怪(和不必要的)ASM 代码
- 封送指向结构异常"cannot Read or Write protected memory"的指针数组的指针数组
- 为什么发出空asm命令会交换变量
- 是否有任何编译器屏障等于 C++11 中的 asm( " " ::: "memory" )?