31

我的问题很简单。为什么没有std::atomic<double> 完全实施?我知道这与原子 RMW(读-修改-写)访问有关。但我真的不明白,为什么在double.

它指定可以使用任何可简单复制的类型。当然double是其中之一。因此,C++11 需要可用于任何类类型的基本操作(加载、存储、CAS、交换等)。

但是,对于整数,可以进行一组额外的操作(fetch_add+++=等)。

Adouble与这些类型几乎没有区别。它是本机的、可简单复制的等。为什么标准不包含double这些类型?


更新:C++20 确实专注std::atomic<T>于浮点类型,带有 fetch_add 和 sub。 C++20 std::atomic<float>- std::atomic<double>.specializations 但不是原子绝对值 (AND) 或否定 (XOR)。

编者注:如果没有 C++20,您可以将自己的代码从 CAS 中推出;有关可移植示例,请参阅x86_64 上的原子双浮点或 SSE/AVX 向量加载/存储;atomic<double>和 float 在大多数 C++ 实现中是无锁的。

4

2 回答 2

22

std::atomic<double>从某种意义上说是受支持的,您可以在程序中创建一个,它将在 C++11 的规则下工作。您可以使用它执行加载和存储,并进行比较交换等。

该标准规定算术运算(+、*、+=、& 等)仅提供给“整数类型”的原子,因此std::atomic<double>不会定义任何这些操作。

我的理解是,由于在当今使用的硬件中几乎不支持 fetch-add 或任何其他针对浮点类型的原子算术运算,因此 C++ 标准没有为它们提供运算符,因为它们的实现效率很低。

(编辑)。顺便说一句,std::atomic<double>在 VS2015RC 中是无锁的。

于 2015-05-05T10:25:31.327 回答
9

标准库要求std::atomic<T>T 是任何TriviallyCopyable类型。既然doubleTriviallyCopyablestd::atomic<double>应该编译和工作得很好。

如果没有,则说明您的库有问题。

编辑:由于评论澄清了问题:

c++ 标准为基本整数类型指定了特定的特化。(即包含需要在语言中出现的整数的类型)。这些专业化对 atomic 的一般情况有进一步的要求,因为它们必须支持:

  • fetch_add
  • fetch_sub
  • fetch_and
  • fetch_or
  • fetch_xor
  • 运算符++
  • 操作员 -
  • 比较和赋值运算符

OR、XOR、AND 当然与浮动类型无关,甚至比较也开始变得棘手(因为需要处理 epsilon)。因此,当没有理由支持需求时,要求图书馆维护者提供特定的专业化似乎是不合理的。

当然,如果给定的架构支持两个双精度的原子异或(它永远不会!),那么当然没有什么可以阻止库维护者提供这种专业化。

于 2015-05-05T09:15:24.287 回答