具体而言,在以下方面是否有任何有效的区别:
i = a.load(memory_order_acquire);或
a.store(5, memory_order_release);和
atomic_thread_fence(memory_order_acquire);
i = a.load(memory_order_relaxed);或
a.store(5, memory_order_relaxed);
atomic_thread_fence(memory_order_release);分别?
非松弛的原子通路提供信号栅栏和线栅栏吗?
发布于 2017-02-11 15:47:14
你需要
atomic_thread_fence(memory_order_release);
a.store(5, memory_order_relaxed);和
i = a.load(memory_order_relaxed);
atomic_thread_fence(memory_order_acquire);取代
a.store(5, memory_order_release);和
i = a.load(memory_order_acquire);不放松的原子通路确实提供信号栅栏以及线栅栏。
发布于 2017-02-11 21:59:02
在您的代码中,对于load和store,fence和原子操作之间的顺序应该颠倒,然后它类似于独立的操作,但也有不同之处。
获取和释放原子变量的操作就像单向的屏障,但方向相反.也就是说,存储/释放操作防止(在程序源中)之前的内存操作在其之后被重新排序,而加载/获取操作则防止在它之前重新排序跟随它的内存操作。
// 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。
将原子操作替换为独立线程围栏和放松操作类似:
// 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指令。它基本上是一个编译器专用的屏障。
https://stackoverflow.com/questions/42177234
复制相似问题