gpt4 book ai didi

c++ - 如何使一个线程 "promptly"中的内存存储在其他线程中可见?

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

假设我想将设备寄存器的内容复制到一个将由多个线程读取的变量中。有没有一个好的通用方法来做到这一点?以下是执行此操作的两种可能方法的示例:

#include <atomic>

volatile int * const Device_reg_ptr = reinterpret_cast<int *>(0x666);

// This variable is read by multiple threads.
std::atomic<int> device_reg_copy;

// ...

// Method 1
const_cast<volatile std::atomic<int> &>(device_reg_copy)
.store(*Device_reg_ptr, std::memory_order_relaxed);

// Method 2
device_reg_copy.store(*Device_reg_ptr, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);

更一般地说,面对可能的整个程序优化,如何正确控制一个线程中内存写入在其他线程中可见的延迟?

编辑:在您的回答中,请考虑以下情况:

  • 代码在嵌入式系统的 CPU 上运行。
  • 单个应用程序正在 CPU 上运行。
  • 应用程序的线程数远远少于 CPU 的处理器内核数。
  • 每个核心都有大量的寄存器。
  • 应用程序足够小,因此在构建其可执行文件时成功使用了整个程序优化。

我们如何确保一个线程中的存储不会无限期地保持对其他线程不可见?

最佳答案

如果您想以原子方式更新 device_reg_copy 的值,那么 device_reg_copy.store(*Device_reg_ptr, std::memory_order_relaxed); 就足够了。

没有必要对原子变量应用volatile,这是不必要的。

std::memory_order_relaxed 存储应该产生最少的同步开销。在 x86 上,它只是一条普通的 mov 指令。

但是,如果您想以这种方式更新它,则任何前面 存储的效果连同 device_reg_copy 的新值对其他线程可见,然后使用 std::memory_order_release 存储,即 device_reg_copy.store(*Device_reg_ptr, std::memory_order_release);。在这种情况下,读者需要将device_reg_copy 加载为std::memory_order_acquire。同样,在 x86 上 std::memory_order_release 存储是一个普通的 mov

而如果您使用最昂贵的 std::memory_order_seq_cst 存储,它会在 x86 上为您插入内存屏障。

这就是为什么他们说 x86 内存模型对于 C++11 来说有点太强了:普通的 mov 指令是 std::memory_order_release on store 和 std::memory_order_acquire 加载。 x86 上没有松弛存储或加载。

我怎么推荐都不为过CPU Cache Flushing Fallacy文章。

关于c++ - 如何使一个线程 "promptly"中的内存存储在其他线程中可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42003798/

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