简体   繁体   English

C++11中获取/释放VS顺序一致性?

[英]Acquire/Release VS Sequential Consistency in C++11?

#include <thread>
#include <atomic>
#include <cassert>

std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};

void write_x()
{
    x.store(true, std::memory_order_release);
}

void write_y()
{
    y.store(true, std::memory_order_release);
}

void read_x_then_y()
{
    while (!x.load(std::memory_order_acquire))
        ;
    if (y.load(std::memory_order_acquire)) {
        ++z;
    }
}

void read_y_then_x()
{
    while (!y.load(std::memory_order_acquire))
        ;
    if (x.load(std::memory_order_acquire)) {
        ++z;
    }
}

int main()
{
    std::thread a(write_x);
    std::thread b(write_y);
    std::thread c(read_x_then_y);
    std::thread d(read_y_then_x);
    a.join(); b.join(); c.join(); d.join();
    assert(z.load() != 0);
}

If I relplace seq_cst to acquire/release in cppreference's last example , can assert(z.load() != 0) be fail ?如果我在cppreference 的最后一个示例中将 seq_cst 替换为获取/释放, assert(z.load() != 0)会失败吗?

  • Seq_CST can prevent StoreLoad reorder, but the code hasn't. Seq_CST 可以阻止 StoreLoad 重新排序,但代码没有。
  • Acquire can prevent LoadLoad reorder. Acquire 可以防止 LoadLoad 重新排序。
  • Release can prevent StoreStore reorder. Release 可以防止 StoreStore 重新排序。

Yes, it is possible that z.load() == 0 in your code if you use acquire / release order as you've done.是的,如果您像您一样使用acquire / release顺序,则您的代码中可能会出现z.load() == 0 There is no happens-before relationship between the independent writes to x and y .xy的独立写入之间没有发生之前的关系。 It's not a coincidence cppreference used that example specifically to illustrate a case where acquire/release isn't sufficient. cppreference 专门使用该示例来说明获取/释放不足的情况并非巧合。

This is sometimes call the IRIW (independent reads of independent writes), and tended to be glossed over in some hardware ordering models.这有时被称为 IRIW(独立写入的独立读取),并且在某些硬件订购模型中往往被掩盖。 In particular, a memory model defined only in terms of the possible load-load, load-store, store-store, etc, reorderings doens't say anything either way really about IRIW.特别是,仅根据可能的加载-加载、加载-存储、存储-存储等定义的内存模型,重新排序并没有真正说明 IRIW。 In the x86 memory model IRIW reordering is disallowed because of a clause that explains that stores have a total order and all processors view stores in this same order.在 x86 内存模型中,IRIW 重新排序是不允许的,因为有一个条款解释了存储具有总顺序并且所有处理器都以相同的顺序查看存储。

I'm not aware if any CPUs in common use admit the IRIW reordering when the barriers and/or instructions needed for acquire and release are used, but I wouldn't be surprised if some do.我不知道当使用获取和释放所需的障碍和/或指令时,是否有任何常用的 CPU 承认 IRIW 重新排序,但如果有人这样做,我不会感到惊讶。

Yes, the assert can fire.是的,断言可以触发。

The principal property that is not guaranteed by acquire / release is a single total order of modifications.不由获取/释放保证的主要属性是修改的单个总顺序。 It only guarantees that (the non-existent) previous actions of a and b are observed by c and d if they see true from the loads.它仅保证ab (不存在的)先前动作被cd观察到,如果它们从负载中看到是true

A (slightly contrived) example of this is on a multi-cpu (physical socket) system that isn't fully cache-coherant.一个(稍微人为的)示例是在不完全缓存一致的多 CPU(物理套接字)系统上。 Die 1 has core A running thread a and core C running thread c . Die 1 具有运行线程a内核 A 和运行线程c内核 C 。 Die 2 has core B running thread b and core D running thread d . Die 2 具有运行线程b内核 B 和运行线程d内核 D 。 The interconnect between the two sockets has a long latency when compared to a memory operation that hits on-die cache.与命中片上缓存的内存操作相比,两个插槽之间的互连具有较长的延迟。

a and b run at the same wall clock time. ab在相同的挂钟时间运行。 C is on-die with A, so can see the store to x immediately, but the interconnect delays it's observation of the store to y , so it sees the old value. C 与 A 一起在芯片上,因此可以立即看到x的存储,但互连将其对存储的观察延迟到y ,因此它看到旧值。 Similarly D is on-die with B, so it sees the store to y , but misses the store to x .类似地,D 与 B 处于死机状态,因此它看到了y的存储,但错过了x的存储。

Whereas if you have sequential consistency, some co-ordination is required to enforce a total order, such as "C and D are blocked while the interconnect syncs the caches".而如果您具有顺序一致性,则需要一些协调来强制执行总顺序,例如“互连同步缓存时 C 和 D 被阻塞”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么“获取/释放”不能保证 c++11 中的顺序一致性? - Why 'acquire/release' can not guarantee sequential consistency in c++11? 获取c ++ 11(原子)的发布操作 - Acquire release operation of c++11(atomic) C ++ 11比较和交换获取/发布语义 - C++11 compare and swap acquire/release semantics C ++ 11 std :: atomic是否保证互斥以及顺序一致性? - Does C++11 std::atomic guarantee mutual exclusion as well as sequential consistency? C++11 顺序一致性 memory 命令是否禁止存储缓冲区石蕊测试? - Does C++11 sequential consistency memory order forbid store buffer litmus test? C++11 memory_order_acquire 和 memory_order_release 语义? - C++11 memory_order_acquire and memory_order_release semantics? 理解 C++11 中的 `memory_order_acquire` 和 `memory_order_release` - Understanding `memory_order_acquire` and `memory_order_release` in C++11 C ++ 11标准是否正式定义了获取,发布和使用操作? - Does the C++11 standard formally define acquire, release, and consume operations? C ++ 11是否允许(不要求)发布/获取volatile关键字的语义 - Does C++11 allow (not require) release/acquire semantics for volatile keyword 抢先式多任务处理是否可以干扰C ++ 11发行获得语义? - Could preemptive multitasking interfere with C++11 release-acquire semantics?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM