web-dev-qa-db-ja.com

アトミックダブルが完全に実装されていないのはなぜですか

私の質問は非常に簡単です。なぜstd::atomic<double>完全に実装 ?私はそれがアトミックRMW(読み取り-変更-書き込み)アクセスに関係していることを知っています。しかし、私は本当にわかりません。これがdoubleで不可能であるべき理由です。

簡単にコピーできる タイプを使用できることが指定されています。そしてもちろんdoubleもその中にあります。したがって、C++ 11には、任意のクラス型で使用できる基本的な操作(ロード、ストア、CAS、交換など)が必要です。

ただし、整数では追加の演算セットが可能です(fetch_add+++=など)。

doubleはこれらのタイプとほとんど変わりません。それはネイティブで、ささいにコピー可能などです。なぜこれらの型にdoubleが標準に含まれていないのですか?


更新:C++ 20はstd::atomic<T>浮動小数点型の場合、fetch_addおよびsubを使用します。 C++ 20 std :: atomic <float>-std :: atomic <double> .specializations ただし、アトミック絶対値(AND)または否定(XOR)ではありません。

編集者注:C++ 20がなくても、独自のCASを展開できます。移植可能な例については Atomic double floating pointまたはSSE/AVX vector load/store on x86_64 を参照してください。 atomic<double>とfloatは、ほとんどのC++実装でロックフリーです。

21
laurisvr

std::atomic<double>は、プログラムで作成でき、C++ 11のルールの下で機能するという意味でサポートされています。それを使用してロードとストアを実行し、比較交換などを行うことができます。

標準では、算術演算(+、*、+ =、&など)は「整数型」のアトミックに対してのみ提供されると規定されているため、std::atomic<double>には、これらの操作が定義されていません。

私の理解では、現在使用中のハードウェアでは、浮動小数点型のフェッチ加算やその他のアトミック算術演算がほとんどサポートされていないため、非効率的に実装する必要があるため、C++標準では演算子を提供していません。

(編集)。余談として、 std::atomic<double> VS2015RCはロックフリーです。

18
Jared Mulconry

標準ライブラリはstd::atomic<T>を要求します。ここでTは任意のTriviallyCopyableタイプです。 doubleTriviallyCopyableであるため、std::atomic<double>は完全にコンパイルおよび動作するはずです。

そうでない場合は、ライブラリに障害があります。

編集:質問を明確にするコメント以降:

C++標準では、基本的な整数型の特定の特殊化を指定しています。 (つまり、言語に存在する必要がある整数を含む型)。これらの特殊化には、以下をサポートする必要があるという点で、アトミックの一般的なケースに対してさらに要件があります。

  • fetch_add
  • fetch_sub
  • fetch_and
  • fetch_or
  • fetch_xor
  • 演算子++
  • オペレーター -
  • 比較および代入演算子

OR、XOR、ANDはもちろん浮動小数点型には関係がなく、実際に比較でさえもトリプロンになります(イプシロンを処理する必要があるため)。したがって、ライブラリメンテナが要求をサポートするケースがないときに特定の専門化を利用可能にすることはmandateには不合理に思われます。

もちろん、preventに特定のアーキテクチャが2つのdoubleのアトミックな排他的論理和をサポートするという万が一の事態に備えて、ライブラリのメンテナがこの特殊化を提供することはありません(絶対にありません!)。

9
Richard Hodges