考虑以下spin_lock()实现,最初来自这个答案:
void spin_lock(volatile bool* lock) {
for (;;) {
// inserts an acquire memory barrier and a compiler barrier
if (!__atomic_test_and_set(lock, __ATOMIC_ACQUIRE))
return;
while (*lock) // no barriers; is it OK?
cpu_relax();
}
}
Run Code Online (Sandbox Code Playgroud)
我所知道的:
volatile防止编译器*lock在while循环的每次迭代中优化重新读取;volatile 不插入内存或编译器障碍 ;x86(例如在Linux内核中)和其他一些架构;spin_lock()执行针对通用体系结构; 这个例子插入它们__atomic_test_and_set().问题:
volatile这里是否足够或者是否存在while循环中需要内存或编译器障碍或原子操作的架构或编译器?
1.1根据C++标准?
1.2在实践中,对于已知的体系结构和编译器,特别是它支持的GCC和平台?
while根据C++11它的内存模型,循环是否安全?有几个相关的问题,但我无法从它们构建一个明确和明确的答案:
原则上:是的,如果程序执行从一个核心移动到下一个核心,则可能看不到在先前核心上发生的所有写入. …
考虑这个程序:
-- Initially --
std::atomic<int> x{0};
int y{0};
-- Thread 1 --
y = 1; // A
x.store(1, std::memory_order_release); // B
x.store(3, std::memory_order_relaxed); // C
-- Thread 2 --
if (x.load(std::memory_order_acquire) == 3) // D
print(y); // E
Run Code Online (Sandbox Code Playgroud)
在 C++11 内存模型下,如果程序打印任何内容,则它会打印 1。
在 C++20 内存模型中,释放顺序已更改以排除由同一线程执行的写入。这对这个程序有何影响?现在可以进行数据竞争并打印 或0吗1?
这段代码出现在P0982R1: Weaken Release Sequences中,我相信这篇论文导致了 C++20 中发布序列定义的更改。在该特定示例中,有第三个线程进行存储,x该存储以违反直觉的方式中断了释放顺序。这激发了削弱发布顺序定义的需要。
通过阅读该论文,我的理解是,随着C++20的变化,C将不再构成以B为首的发布序列的一部分,因为C不是读-修改-写操作。因此C不与D同步。因此A和E之间不存在happens-before关系。
由于 B 和 C 存储到同一个原子变量,并且所有线程必须就该变量的修改顺序达成一致,因此 C++20 内存模型是否允许我们推断 A 是否发生在 E 之前?
与我之前的问题类似,请考虑以下代码
-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 2 --
y.store(2, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire); // x first
int r2 = y.load(std::memory_order_acquire);
-- Thread 4 --
int r3 = y.load(std::memory_order_acquire); // y first
int r4 = x.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)
是怪异的结果 r1==1, r2==0,并r3==2, r4==0有可能在C ++ 11内存模型下,这种情况下?如果我要全部替换std::memory_order_acq_rel成该std::memory_order_relaxed怎么办?
在x86上,这样的结果似乎是被禁止的,请参见此SO问题,但我一般是在询问C ++ 11内存模型。
奖励问题:
我们都同意,与std::memory_order_seq_cst该怪异的结果不会在C ++ 11被允许。现在,赫伯·萨特(Herb Sutter)在他著名的- …
c++ ×3
concurrency ×2
memory-model ×2
atomic ×1
c++11 ×1
c++20 ×1
gcc ×1
spinlock ×1
stdatomic ×1