gpt4 book ai didi

c++ - 标准 C++11 是否保证 `volatile atomic` 具有两种语义( volatile + 原子)?

转载 作者:IT老高 更新时间:2023-10-28 21:58:30 29 4
gpt4 key购买 nike

众所周知,std::atomicvolatile是不同的东西。

有两个主要区别:

  1. 两个优化可以用于 std::atomic<int> a; , 但不能用于 volatile int a; :

    • 融合操作:a = 1; a = 2;可以由 a = 2; 上的编译器替换
    • 不断传播:a = 1; local = a;可以由 a = 1; local = 1; 上的编译器替换
  2. 跨原子/ volatile 操作的普通读/写重新排序:

    • volatile int a;任何 volatile 读/写操作都不能重新排序。但是附近的普通读/写仍然可以围绕 volatile 读/写重新排序。
    • std::atomic a;基于用于原子操作的内存屏障限制附近普通读/写的重新排序a.load(std::memory_order_...);

volatile不要引入内存栅栏,而是 std::atomic可以做到。

正如文章中所描述的那样:

例如,std::atomic应该用于并发多线程程序(CPU-Core <-> CPU-Core),但是volatile应该用于访问设备上的内存映射区域(CPU-Core <-> Device)。


但如果需要,它们都具有不寻常的语义,并具有无锁编码所需的任何或全部原子性和/或顺序保证,即如果需要 volatile std::atomic<> , 需要几个原因:

  • 排序:防止对普通读/写进行重新排序,例如,从 CPU-RAM 中读取数据,使用设备 DMA Controller 将数据写入其中

例如:

char cpu_ram_data_written_by_device[1024];
device_dma_will_write_here( cpu_ram_data_written_by_device );

// physically mapped to device register
volatile bool *device_ready = get_pointer_device_ready_flag();

//... somewhere much later
while(!device_ready); // spin-lock (here should be memory fence!!!)
for(auto &i : cpu_ram_data_written_by_device) std::cout << i;

示例:

char cpu_ram_data_will_read_by_device[1024];
device_dma_will_read_it( cpu_ram_data_written_by_device );

// physically mapped to device register
volatile bool *data_ready = get_pointer_data_ready_flag();

//... somewhere much later
for(auto &i : cpu_ram_data_will_read_by_device) i = 10;
data_ready=true; //spilling cpu_ram_data_will_read_by_device to RAM, should be memory fence
  • 原子:保证 volatile 操作是原子的 - 即它将由单个操作而不是多个 - 即一个 8 字节操作而不是两个 4 字节操作组成

为此,Herb Sutter 谈到了 volatile atomic<T> ,2009 年 1 月 8 日:http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2

Finally, to express a variable that both has unusual semantics and has any or all of the atomicity and/or ordering guarantees needed for lock-free coding, only the ISO C++0x draft Standard provides a direct way to spell it: volatile atomic.

但是现代标准 C++11(不是 C++0x 草案)、C++14 和 C++17 是否保证 volatile atomic<T>具有两种语义( volatile +原子)?

是否 volatile atomic<T>从 volatile 和 atomic 保证最严格的保证?

  1. volatile :避免问题开头所述的融合操作和持续传播
  2. std::atomic :引入内存栅栏以提供排序、溢出和原子性。

我们能做到吗reinterpret_cast来自 volatile int *ptr;volatile std::atomic<int>* ?

最佳答案

是的,确实如此。

第 29.6.5 节,“对原子类型的操作要求”

Many operations are volatile-qualified. The “volatile as device register” semantics have not changed in the standard. This qualification means that volatility is preserved when applying these operations to volatile objects.

我检查了 2008 年到 2016 年的工作草案,所有这些草案中的文本都是相同的。因此它应该应用 C++11、C++14 和 C++17。

关于c++ - 标准 C++11 是否保证 `volatile atomic<T>` 具有两种语义( volatile + 原子)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40367079/

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