最低订购要求

Posted

技术标签:

【中文标题】最低订购要求【英文标题】:A Minimum Ordering Requirement 【发布时间】:2019-12-30 13:10:29 【问题描述】:

xystd::atomic<int> 类型的两个不同变量,并假设它们的当前值都是1。什么是最宽松的一组订购要求,因此以下代码会生成一些输出? (即,order1 ... order4 应该使用什么?)

// Thread 1
x.store(0, order1);       // A
if(0 == y.load(order2))   // B
  std::cout << '1';       // C
// Thread 2
y.store(0, order3);       // E
if(0 == x.load(order4))   // F
  std::cout << '2';       // G

【问题讨论】:

不清楚。您的代码中没有 x 和 y。 w 是什么? s 是什么? some output - 有输出吗?这意味着您希望执行点CG 之一或同时执行点CG 我不认为有任何订购要求的组合可以保证程序输出任何东西。 我认为顺序一致的排序应该保证some output。另外relaxedacquire_relacquire_consume 不能保证some output 【参考方案1】:

您需要所有操作的顺序一致性。

Release/acquire 在这里实际上并没有强加任何顺序,因为在 release-store 之前没有 store 或者在 acquire-load 之后没有加载,这将由它来排序。

任何商店的轻松内存排序,例如x.store 可能导致商店在两个线程中以不同的顺序可见。然后,它不会违反其余操作的顺序,以在另一个线程中加载后使松弛存储可见,而另一个存储在其相应加载后仍按顺序一致的总顺序排序。

保证所有操作输出的顺序排序,因为在所有线程中必须以相同的方式观察到顺序操作的总顺序。此顺序必须与线程中的排序顺序一致,即x.store &lt; y.loady.store &lt; x.load。唯一的可能是:

x.store < y.load  < y.store < x.load
x.store < y.store < x.load  < y.load
x.store < y.store < y.load  < x.load

y.store < x.load  < x.store < y.load
y.store < x.store < y.load  < x.load
y.store < x.store < x.load  < y.load

所有这些都在存储后观察其中一个变量的加载,触发cout 语句之一。

如果例如x.store 不是memory_order_seq_cst,那么,虽然它仍然需要在线程 1 中的 y.load 之前排序,但它可以在线程 2 中的 x.load 之后变得可见。

y.load &lt; y.store &lt; x.load 仍然会满足其他操作的顺序一致性,并且无论如何x 的修改顺序是微不足道的。

【讨论】:

你说,“这个顺序必须与线程中的排序顺序一致”。但是根据en.cppreference.com/w/cpp/atomic/…“单个总顺序可能与happens-before不一致。这允许更有效地实现......”。我错过了什么吗? @Koosha 这仅适用于 C++20。更改是由于p0668r5,但我还没有阅读。我认为这不会改变我的回答。 @Koosha 正如你在 cppreference 页面上看到的那样,总顺序与 happens-before 关系一致的要求已被弱化为与 strongly occur-before 关系,但 sequenced-before 仍然暗示 strongly occur-before 并且我只使用 sequenced-before i> 我的回答中的关系。【参考方案2】:

#StoreLoad 重新排序会导致两个加载都返回旧值,因此您需要对所有 4 个操作进行完全的顺序一致性来防止这种情况。

阅读存储缓冲区以了解导致此类重新排序的原因。

【讨论】:

【参考方案3】:

两个简单的规则:

作为并行启动(线程启动)后的第一个操作,释放栅栏或操作没有任何可见的内容(在其他线程中),因此没有“释放”并且释放是无用的(一切都是以前可见,并且对同时启动的线程同样可见); 作为并行性结束(线程结束)之前的最后一个操作,获取栅栏或操作没有任何可以显示(在该线程中)在公共父线程中不可见的内容

这里有:

x.store(0, order1);       // A
if(0 == y.load(order2))   // B
一开始的商店 最后一个负载

所以无论是获取还是释放语义都不会产生任何差异。

【讨论】:

以上是关于最低订购要求的主要内容,如果未能解决你的问题,请参考以下文章

openwrt最低配置要求

windows11最低配置要求

请求具有最低精度要求的地理定位

Android 上的 Kotlin - 是不是有最低 API 级别要求?

ipad app 最低操作系统要求错误

ClickOnce部署最低要求版本自动增加MSBuild