首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C++中,获取/释放原子访问和宽松的访问与围栏相结合是否有任何有效的区别?

在C++中,获取/释放原子访问和宽松的访问与围栏相结合是否有任何有效的区别?
EN

Stack Overflow用户
提问于 2017-02-11 14:51:14
回答 2查看 567关注 0票数 4

具体而言,在以下方面是否有任何有效的区别:

代码语言:javascript
运行
复制
i = a.load(memory_order_acquire);

代码语言:javascript
运行
复制
a.store(5, memory_order_release);

代码语言:javascript
运行
复制
atomic_thread_fence(memory_order_acquire);
i = a.load(memory_order_relaxed);

代码语言:javascript
运行
复制
a.store(5, memory_order_relaxed);
atomic_thread_fence(memory_order_release);

分别?

非松弛的原子通路提供信号栅栏和线栅栏吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-11 15:47:14

你需要

代码语言:javascript
运行
复制
atomic_thread_fence(memory_order_release);
a.store(5, memory_order_relaxed);

代码语言:javascript
运行
复制
i = a.load(memory_order_relaxed);
atomic_thread_fence(memory_order_acquire);

取代

代码语言:javascript
运行
复制
a.store(5, memory_order_release);

代码语言:javascript
运行
复制
i = a.load(memory_order_acquire);

不放松的原子通路确实提供信号栅栏以及线栅栏。

票数 3
EN

Stack Overflow用户

发布于 2017-02-11 21:59:02

在您的代码中,对于loadstore,fence和原子操作之间的顺序应该颠倒,然后它类似于独立的操作,但也有不同之处。

获取和释放原子变量的操作就像单向的屏障,但方向相反.也就是说,存储/释放操作防止(在程序源中)之前的内存操作在其之后被重新排序,而加载/获取操作则防止在它之前重新排序跟随它的内存操作。

代码语言:javascript
运行
复制
// thread 1
// shared memory operations A
a.store(5, std::memory_order_release);

x = 42; // regular int


// thread 2
while (a.load(std::memory_order_acquire) != 5);
// shared memory operations B

内存操作A不能向下移动到store/release以下,而内存操作B不能在load/acquire之上移动。当线程2读取5时,存储器操作A对B可见,同步完成。

作为一个单向障碍,对x的写可以加入,甚至在内存操作A之前,但是由于它不是获取/释放关系的一部分,所以线程2无法可靠地访问x

将原子操作替换为独立线程围栏和放松操作类似:

代码语言:javascript
运行
复制
// thread 1
// shared memory operations A
std::atomic_thread_fence(memory_order_release);
a.store(5, std::memory_order_relaxed);


// thread 2
while (a.load(std::memory_order_relaxed) != 5);
std::atomic_thread_fence(memory_order_acquire);
// shared memory operations B

这取得了同样的结果,但一个重要的区别是,这两个栅栏并不是单向的屏障;如果是这样的话,到a的原子存储可以在释放栅栏之前重新排序,而来自a的原子负载可以在获取栅栏之后重新排序,这将破坏同步关系。

一般而言:

  • 独立的释放栅栏可以防止前面的操作被重新排序,然后是(原子)存储。
  • 独立获取栅栏可以防止后续操作与(原子)前面的负载重新排序。

该标准允许获取/释放围栏与获取/释放操作混合。

非松弛的原子通路提供信号栅栏和线栅栏吗?

我不完全清楚您在这里问什么,因为线程栅栏通常与轻松的原子操作一起使用,但是std::thread_signal_fence类似于一个std::atomic_thread_fence,只是它应该在同一个线程中操作,因此编译器不会生成用于线程间同步的CPU指令。它基本上是一个编译器专用的屏障。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42177234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档