是否可以在 C++11 中使用后续顺序一致加载对存储版本进行重新排序
Can a store-release be reordered with a subsequent sequential-consistent load in C++11?
具有std::memory_order_release
到某个位置的存储可以通过后续加载从另一个位置重新排序,并具有std::memory_order_acquire
。
但是,可以将std::memory_order_release
到某个位置的商店重新排序,然后从另一个位置加载std::memory_order_seq_cst
吗?
类似地,与变量std::memory_order_seq_cst
的存储是否可以通过后续加载从另一个位置重新排序std::memory_order_acquire
?
请考虑以下示例:
std::atomic<int> x{0};
std::atomic<int> y{0};
void thread1() {
x.store(std::memory_order_release, 1);
int r1 = y.load(std::memory_order_seq_cst);
std::cout << r1 << std::endl;
}
void thread2() {
y.store(std::memory_order_seq_cst, 1);
int r2 = x.load(std::memory_order_acquire);
std::cout << r2 << std::endl;
}
众所周知(http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/),如果两个std::memory_order_seq_cst
都被它们的释放/获取对应物替换,则输出可能是两倍"0"。
在这个例子中,顺序一致性是否买了什么东西,或者输出仍然可以是两倍"0"?
不,在这个例子中,顺序一致性不会购买任何东西,输出仍然可以是"0"的两倍。
std::memory_order_seq_cst
和 std::memory_order_acquire/release
之间的唯一区别是std::memory_order_seq_cst
存储可能不会随着后续std::memory_order_seq_cst
加载到不同的变量/位置而重新排序,请参阅 Herb Sutter 的"原子<>武器"演讲。(当然,存储可能永远不会随着后续加载到同一变量而重新排序。
但是,一旦只有一个(更不用说两个)内存顺序被削弱(就像示例中两个线程的情况一样),StoreLoad 重新排序可能会发生。这意味着,在示例中,两个负载可以在各自的存储之前重新排序。
这意味着,如果一个程序将孤独的std::memory_order_seq_cst
替换为std::memory_order_release
(如果它带有商店)或std::memory_order_acquire
(如果它带有负载),则只包含一个std::memory_order_seq_cst
并且仅包含std::memory_order_release/acquire
的程序仍然是相同的程序。
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- C++:将控制台输出存储在宏中更好吗
- 导入库可以跨dll版本工作吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 存储模板类型以强制转换回派生<T>
- 类型总是使用其大小存储在内存中吗
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 使用无符号字符数组有效存储内存
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 带结构的二维矢量:如何存储元素
- 是否可以在 C++11 中使用后续顺序一致加载对存储版本进行重新排序
- 支持C++11的有缺陷编译器版本的存储库