gpt4 book ai didi

c++ - 在 C++ 中,获取/释放原子访问与宽松访问与栅栏相结合之间是否存在任何有效区别?

转载 作者:太空狗 更新时间:2023-10-29 20:35:35 25 4
gpt4 key购买 nike

具体来说,两者之间是否有任何有效的区别:

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);

分别是?

非松弛原子访问是否提供信号栅栏和线程栅栏?

最佳答案

在你的代码中,对于loadstore,fence和atomic operation之间的顺序应该是相反的,然后它类似于standalone操作,但是有区别。

对原子变量的获取和释放操作充当单向屏障,但方向相反。也就是说,store/release 操作会阻止在它之前(在程序源中)的内存操作在它之后重新排序,而 load/acquire 操作会阻止在它之后的内存操作在它之前被重新排序。

// 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,但由于它不是获取/释放关系的一部分 x 不能被线程 2 可靠地访问。

用独立线程栅栏和宽松操作替换原子操作是类似的:

// 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 的原子加载进行重新排序,并且这会破坏同步关系。

一般来说:

  • 独立的发布栅栏可防止前面的操作被后面的(原子)存储重新排序。
  • 独立获取栅栏可防止后续操作被其之前的(原子)加载重新排序。

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

Do non-relaxed atomic accesses provide signal fences as well as thread fences?

我不太清楚你在这里问什么,因为线程栅栏通常用于宽松的原子操作,但是 std::thread_signal_fence 类似于 std::atomic_thread_fence,只是它应该在同一个线程中运行并且因此编译器不会生成用于线程间同步的 CPU 指令。它基本上充当仅编译器的障碍。

关于c++ - 在 C++ 中,获取/释放原子访问与宽松访问与栅栏相结合之间是否存在任何有效区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42177234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com