gpt4 book ai didi

c++ - 内存模型,负载获取语义实际上是如何工作的?

转载 作者:行者123 更新时间:2023-11-30 01:01:37 25 4
gpt4 key购买 nike

来自非常好Paperarticle关于内存重新排序。

Q1:我了解缓存一致性、存储缓冲区和失效队列是内存的根本原因重新排序?

Store release 很好理解,必须等待所有加载和存储完成后才能将标志设置为 true。

关于加载获取,原子加载的典型用法是等待标志。假设我们有 2 个线程:

int x = 0;
std::atomic<bool> ready_flag = false;
// thread-1
if(ready_flag.load(std::memory_order_relaxed))
{
// (1)
// load x here
}
// (2)
// load x here
// thread-2
x = 100;
ready_flag.store(true, std::memory_order_release);

编辑:在线程 1 中,它应该是一个 while 循环,但我从上面的文章中复制了逻辑。因此,假设内存重新排序是及时发生的。

Q2:因为(1)和(2)取决于if条件,CPU必须等待ready_flag,这是否意味着write-release就足够了?在此上下文中如何进行内存重新排序?

Q3:显然我们有load-acquire,所以我猜mem-reorder是可能的,那么我们应该把fence放在哪里, (1) 还是 (2)?

最佳答案

访问原子变量不是互斥操作;它只是原子地访问存储的值,任何 CPU 操作都没有机会中断访问,这样就不会发生关于访问该值的数据竞争(它还可以针对其他访问发出障碍,这就是内存命令提供)。但仅此而已;它不会等待任何特定值出现在原子变量中。

因此,您的 if 语句将读取当时恰好存在的任何值。如果你想保护对 x 的访问,直到另一个语句写入它并发出原子信号,你必须:

  1. 在原子标志返回值true 之前,不允许任何代码x 中读取。仅仅测试一次值是不行的;您必须遍历重复访问,直到它为 true。任何其他从 x 读取的尝试都会导致数据竞争,因此是未定义的行为。

  2. 无论何时访问该标志,您都必须以一种方式这样做,告诉系统线程设置该标志写入的值应该对看到设置值的后续操作可见。这需要一个正确的内存顺序,必须至少为 memory_order_acquire

    从技术上讲,读取标志本身并不一定要进行获取。从标志中读取正确的值后,您可以执行获取操作。但是在读取 x 之前,您需要进行等效的获取操作。

  3. 写入语句必须使用至少与 memory_order_release 一样强大的释放内存顺序来设置标志。

关于c++ - 内存模型,负载获取语义实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58804138/

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