C++ 20中acquire操作的定义在哪里?

rel*_*t95 4 c++ atomic memory-barriers language-lawyer stdatomic

我正在阅读cppreference.com 上的std::memory_order和C++ 20 规范。我找不到术语“获取操作”和“释放操作”的定义。

第一个文档递归地定义了这些术语,表示“具有 memory_order_acquire 或更强的原子加载是一个获取操作”。和“memory_order_acquire:使用此内存顺序的加载操作在受影响的内存位置上执行获取操作。”

第二份文件似乎使用了这些术语,但没有任何定义。它开始使用这些术语,表示“一个或多个内存位置上的同步操作要么是消耗操作、获取操作、释放操作,要么是获取和释放操作。”

所以我用谷歌搜索并找到了LINUX KERNEL MEMORY BARRIERS,它清楚地定义了如下术语。

(5) 获取操作。

这起到了单向渗透屏障的作用。它保证 ACQUIRE 操作之后的所有内存操作看起来都发生在相对于系统的其他组件的 ACQUIRE 操作之后。ACQUIRE 操作包括 LOCK 操作以及 smp_load_acquire() 和 smp_cond_load_acquire() 操作。

在 ACQUIRE 操作之前发生的内存操作可能看起来是在 ACQUIRE 操作完成之后发生的。

ACQUIRE 操作几乎总是与 RELEASE 操作配对。

这个定义与作者对术语“获取操作”的含义完全相同吗?

Jan*_*tke 7

您引用的定义不是递归的,它只是一个定义;但是,它的格式不正确。\n该标准通常使用斜体文本来指示何时定义术语,我相信这应该应用于此处:

\n
\n

memory_order\xe2\x80\x8b::\xe2\x80\x8bacquirememory_order\xe2\x80\x8b::\xe2\x80\x8bacq_rel、 和memory_order\xe2\x80\x8b::\xe2\x80\x8bseq_cst:加载操作执行获取操作在受影响的内存位置上

\n
\n

- [原子顺序]

\n

此类获取操作的所有属性(最重要的是,释放操作与其同步)在其他地方定义,包括在下一段中:

\n
\n

对原子对象A执行释放操作的原子操作与对原子对象执行获取操作的M原子操作同步,并从以 开头的释放序列中的任何副作用中获取其值。BMA

\n
\n

- [原子顺序] p2

\n

同步及其效果在[intro.races]中定义。

\n

简而言之,加载使用std::memory_order::acquire获取操作,这意味着释放操作与其同步。这种同步是明确定义的。没有什么是递归的;然而,格式具有误导性。

\n
\n

注意:这个答案主要与 C++ 标准相关,但相同的逻辑也可以应用于 cppreference 文章。

\n

注意:我已经在 C++ 草稿存储库中打开了有关此问题的编辑问题。

\n

  • @relent95我不确定你在哪里仍然看到递归。术语“同步”使用术语“获取操作”,“获取操作”(表面上)被定义为涉及 `std::memory_order::acquire` 的操作。递归在哪里?cppreference 文章基本上只是总结了标准在各个部分中关于原子操作的影响的内容。(这来自于“同步于”、“发生在之前”等关系) (4认同)
  • @relent95:是的,这是这些术语的标准含义,并非特定于 C++。https://preshing.com/20120913/acquire-and-release-semantics/。ISO C++ 标准确实定义了需要哪些操作来查看哪些内容的正式规则,因此从这个意义上来说,它确实定义了获取/释放。如果获取负载从不与任何内容同步,则没有实际要求对任何内容进行排序,并且 ISO C++ 避免在对相干缓存的访问的本地重新排序方面指定任何内容,仅指定基于可见性规则的形式模型。 (2认同)