C++11 是否保证释放围栏和使用操作之间的内存顺序
Does C++11 guarantee memory ordering between a release fence and a consume operation?
请考虑以下代码:
struct payload
{
std::atomic< int > value;
};
std::atomic< payload* > pointer( nullptr );
void thread_a()
{
payload* p = new payload();
p->value.store( 10, std::memory_order_relaxed );
std::atomic_thread_fence( std::memory_order_release );
pointer.store( p, std::memory_order_relaxed );
}
void thread_b()
{
payload* p = pointer.load( std::memory_order_consume );
if ( p )
{
printf( "%dn", p->value.load( std::memory_order_relaxed ) );
}
}
C++是否保证线程 a 中的栅栏与线程 b 中的消耗操作的交互?
我知道在此示例中,我可以用商店发布替换围栏 + 原子存储并让它工作。 但我的问题是关于使用围栏的这种特殊情况。
阅读标准文本,我可以找到有关释放围栏与获取围栏以及释放围栏与获取操作交互的子句,但没有关于释放围栏和使用操作交互的任何子句。
我认为,用获取替换消耗将使代码符合标准。 但据我了解处理器实现的内存排序约束,我应该只真正要求线程 b 中较弱的"消耗"排序,因为内存屏障强制线程 a 中的所有存储在存储指向指针之前可见,并且读取有效负载取决于从指针读取。
标准是否一致?
你的代码有效。
我知道在此示例中,我可以用商店发布替换围栏 + 原子存储并让它工作。但我的问题是关于使用围栏的这种特殊情况。
具有松弛原子操作的围栏比相应的原子操作更强。 例如(来自 http://en.cppreference.com/w/cpp/atomic/atomic_thread_fence,注释):
原子存储释放操作阻止所有先前的写入通过存储发布,而具有memory_order_release排序的atomic_thread_fence阻止所有先前的写入通过所有后续存储。
尽管这显然是意图,但指定栅栏和原子操作交互的方式意味着官方仅支持列出的组合。(这种规范风格不仅冗长,难以阅读,更难转化为有效的直觉,很容易使不完整。
我在标准支持中看不到任何将消费操作与发布屏障配对的内容,即使正常实现不可能不支持,除非在全局程序优化期间通过特殊努力来检测该特定用例并故意破坏它。
相关文章:
- 复制和交换习惯用法与移动操作之间的交互
- "+=" 操作在类型之间不起作用 std::复杂<double>和__complex__双精度
- 我是否应该避免在循环中的常数之间进行操作
- C++模板 - 实例之间的通用操作和成员可见性
- 在'string=string+s1'和"string+=s1"之间移动语义可以保存多少个复制操作?
- _Complex 和 std::complex 之间的 C/C++ 互操作
- 嵌入式串行读取操作和桌面PC之间可能有什么区别
- 是整数舍入规则决定了 C++、python3 和 python2.7 之间的 % 操作差异吗?
- 两个 UShorts 之间的操作在 VC2015 中给出了一个 int
- 开放MP;嵌套循环之间的操作
- C++类和OpenCV矩阵操作之间的转换
- 整数/浮点数/字符串值之间的操作,组合太多
- 仅使用位操作(不使用分支)将16位带符号值约束在0和4095之间
- std::set::迭代器和std::set::const_iterator之间是否存在操作差异
- 操作之间的关系中的对象类型是什么?
- WinRT 组件内C++类之间的互操作
- 类和字符串之间的重载操作
- 图像操作2个图像之间的差异
- 计算c++中操作之间的时间长度
- C++11 是否保证释放围栏和使用操作之间的内存顺序