compare_exchange_strong/weak 可能会看到旧值吗?
Can a compare_exchange_strong/weak potentially see an older value?
我实现了一个并发算法,其中我使用了大量的比较和交换。现在,我想通过调整内存顺序来优化吞吐量,这让我想到了几个特定的问题。它基本上归结为以下代码结构:
atomic_int x = 0;
void thread1() {
int a = atomic_load_explicit(&x, memory_order_relaxed);
compare_exchange_strong_explicit(&x, &a, 1, memory_order_relaxed, memory_order_relaxed);
a = atomic_load_explicit(&x, memory_order_relaxed);
}
void thread2() {
int a = 0;
compare_exchange_strong_explicit(&x, &a, 2, memory_order_relaxed, memory_order_relaxed);
}
现在假设线程 2 的 compare_exchange 成功,线程 1 加载旧值 0 仍然可能发生。 但是,第一个线程的比较交换是否也成功, 因为基础操作仍然看到旧的(预期的)值?
如果不是,那么在这种情况下比较交换显然失败了。但是第二个负载呢? 由于内存顺序放宽,它还能读取旧值吗? compare_exchange 是否为该特定线程“强制”刷新内存子系统?
提前致谢!
保证对特定原子对象的所有原子操作以相同的所谓对象修改顺序对每个线程可见,即它们始终一致地出现。 (否则原子学的整个概念无论如何对我来说都没有多大意义。)
另一方面,当各个线程感知到变化时完全取决于“实现”,即编译器 and/or 运行时。因为体系结构与您所期望的有很大不同,这里,这是 C 标准称之为“实现质量”的问题,也就是说,如果您认为它们是太慢了,例如
我实现了一个并发算法,其中我使用了大量的比较和交换。现在,我想通过调整内存顺序来优化吞吐量,这让我想到了几个特定的问题。它基本上归结为以下代码结构:
atomic_int x = 0;
void thread1() {
int a = atomic_load_explicit(&x, memory_order_relaxed);
compare_exchange_strong_explicit(&x, &a, 1, memory_order_relaxed, memory_order_relaxed);
a = atomic_load_explicit(&x, memory_order_relaxed);
}
void thread2() {
int a = 0;
compare_exchange_strong_explicit(&x, &a, 2, memory_order_relaxed, memory_order_relaxed);
}
现在假设线程 2 的 compare_exchange 成功,线程 1 加载旧值 0 仍然可能发生。 但是,第一个线程的比较交换是否也成功, 因为基础操作仍然看到旧的(预期的)值?
如果不是,那么在这种情况下比较交换显然失败了。但是第二个负载呢? 由于内存顺序放宽,它还能读取旧值吗? compare_exchange 是否为该特定线程“强制”刷新内存子系统?
提前致谢!
保证对特定原子对象的所有原子操作以相同的所谓对象修改顺序对每个线程可见,即它们始终一致地出现。 (否则原子学的整个概念无论如何对我来说都没有多大意义。)
另一方面,当各个线程感知到变化时完全取决于“实现”,即编译器 and/or 运行时。因为体系结构与您所期望的有很大不同,这里,这是 C 标准称之为“实现质量”的问题,也就是说,如果您认为它们是太慢了,例如