gpt4 book ai didi

c++ - 独立于消耗原子负载的变量对操作有什么影响吗?

转载 作者:搜寻专家 更新时间:2023-10-31 01:34:47 26 4
gpt4 key购买 nike

众所周知,有 6 个 std::memory_order's , 以及其中的 2 个:

  • 用于加载的获取语义 - 避免重新排序 Load-Load 和 Load-Store
  • 用于存储的发布语义 - 避免重新排序 Store-Store 和 Load-Store

enter image description here

即对于获取语义,只有S = local1;可以在X.load(std::memory_order_acquire);之后执行:

static std::atomic<int> X;
static int L, S;
...

void thread_func()
{
int local1 = L; // load(L)-load(X) - !!! can be reordered with X !!!
S = local1; // store(S)-load(X) - !!! can be reordered with X !!!

int x_local = X.load(std::memory_order_acquire); // load(X)

int local2 = L; // load(X)-load(L) - can't be reordered with X
S = local2; // load(X)-store(S) - can't be reordered with X
}

但是 load(X) 中的哪些重新排序可以用于消费语义?

static std::atomic<int *> X;
static int L1, L2, S1, S2;
static int L, S;
...

void thread_func()
{
int *x_ptr_local = new int(1);


int local1 = L1; // load(L1)-load(X) - !!! can be reordered with X !!!
S1 = local1; // store(S1)-load(X) - !!! can be reordered with X !!!

int dependent_x1 = *x_ptr_local; // load(x_ptr)-load(X) - !!! can be reordered with X !!!
S = dependent_x1; // store(S)-load(X) - !!! can be reordered with X !!!

x_ptr_local = X.load(std::memory_order_consume); // load(X)

int dependent_x2 = *x_ptr_local; // load(X)-load(x_ptr) - can't be reordered with X
S = dependent_x2; // load(X)-store(S) - can't be reordered with X

int local2 = L2; // load(X)-load(L2) - !!! can be reordered with X !!!
S2 = local2; // load(X)-store(S2) - !!! can be reordered with X !!!
}

是真的吗,只有 dependent_x2 的操作不能跨 X.load(std::memory_order_consume) 重新排序?

以及所有使用变量L1L2S1S2dependent_x1< 的操作 可以跨 X.load(std::memory_order_consume) 重新排序 - 即可以在 X.load(std::memory_order_consume) 之前或之后执行,是不是吗?

最佳答案

memory_order_consume用于保留原子对象本身的数据依赖关系的顺序,而不使用更重的同步,例如 memory_order_acquire 引入的同步。 .与 memory_order_acquire , 所有 acquire 之后的内存操作-- 取决于原子变量或其他 -- 禁止在它之前重新排序,而 memory_order_consume仅禁止重新排序相关 指令。这有利于更弱排序的架构,例如 ARM 和 PowerPC,它们可以保证数据相关指令的排序,而无需显式屏障。

memory_order_consume处理数据依赖性,它的大多数用例涉及 std::atomic<T*> .生产者线程可以构建一个完整的数据结构,并使用 memory_order_release 将该数据结构的地址发布到原子指针。 .消费者线程然后用 memory_order_consume 加载原子指针如果它们以数据相关的方式使用指针,例如通过取消引用它,则可以与编写器线程的存储建立数据依赖性。该标准保证任何依赖加载都将反射(reflect)编写器线程的存储。由于原子变量的加载是通过 memory_order_consume 完成的但是,从读者线程的角度来看,不能保证自变量的状态。

在您的第一个示例中,memory_order_acquire 之后没有负载可以在它之前重新排序。但是,在您的第二个示例中,任何不依赖于 X 的重新排序或者它的加载值是公平的游戏。即 int dependent_x2 = *x_ptr_local; (以及来自 dependent_x2 的相应负载)保证相对于 X 保持有序。 ,但仅此而已。所有其他重新排序都是可能的。

关于c++ - 独立于消耗原子负载的变量对操作有什么影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38673808/

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