私は長年、スレッド実行制御にvolatile boolを使用してきましたが、うまくいきました。
// in my class declaration
volatile bool stop_;
-----------------
// In the thread function
while (!stop_)
{
do_things();
}
さて、c ++ 11がアトミック操作のサポートを追加したので、代わりにそれを試してみることにしました
// in my class declaration
std::atomic<bool> stop_;
-----------------
// In the thread function
while (!stop_)
{
do_things();
}
しかし、それはvolatile bool
よりも数桁遅いです!
私が書いた簡単なテストケースは、volatile bool
アプローチで完了するのに約1秒かかります。 std::atomic<bool>
で、しかし、私は約10分間待ってあきらめました!
load
とstore
でmemory_order_relaxed
フラグを使用して同じ効果を得ようとしました。
私のプラットフォーム:Windows 7 64ビットMinGW gcc 4.6.x
私が間違っているのは何ですか?
[〜#〜] upd [〜#〜]
はい、volatileは変数をスレッドセーフにしません。私の質問は、揮発性についてではなく、アトミックがとてつもなく遅い理由です。
PD2 @all、コメントありがとうございます-今夜、マシンに着いたら、すべての提案を試してみます。
「Olaf Dietsche」のコード
USE ATOMIC
real 0m1.958s
user 0m1.957s
sys 0m0.000s
USE VOLATILE
real 0m1.966s
user 0m1.953s
sys 0m0.010s
GCC SMALLER 4.7を使用している場合
http://gcc.gnu.org/gcc-4.7/changes.html
C++ 11/C11メモリモデルを指定するアトミック操作のサポートが追加されました。これらの新しい__atomicルーチンは、既存の__sync組み込みルーチンを置き換えます。
アトミックサポートは、メモリブロックでも利用できます。メモリブロックがサポートされている整数型と同じサイズとアライメントである場合、ロックフリー命令が使用されます。ロックフリーをサポートしていないアトミック操作は、関数呼び出しとして残されます。ライブラリ関数のセットは、GCC atomic wikiの「External Atomics Library」セクションで利用できます。
そうそう..唯一の解決策はGCC 4.7にアップグレードすることです
これに興味があるので、Ubuntu 12.04、AMD 2.3 GHz、gcc 4.6.3で自分でテストしました。
#if 1
#include <atomic>
std::atomic<bool> stop_(false);
#else
volatile bool stop_ = false;
#endif
int main(int argc, char **argv)
{
long n = 1000000000;
while (!stop_) {
if (--n < 0)
stop_ = true;
}
return 0;
}
g++ -g -std=c++0x -O3 a.cpp
でコンパイル
ただし、@ alegunaと同じ結論:
ちょうどbool
:
実際の0m0.004s
ユーザー0m0.000s
sys 0m0.004s
volatile bool
:
$ time ./a.out
実際の0m1.413s
ユーザー0m1.368s
sys 0m0.008s
std::atomic<bool>
:
$ time ./a.out
実際の0m32.550s
ユーザー0m32.466s
sys 0m0.008s
std::atomic<int>
:
$ time ./a.out
実際の0m32.091s
ユーザー0m31.958s
sys 0m0.012s
私の推測では、これはハードウェアの質問です。 volatileを記述するとき、変数について何も想定しないようコンパイラーに指示しますが、私が理解しているように、ハードウェアはそれを通常の変数として扱います。これは、変数が常にキャッシュにあることを意味します。アトミックを使用する場合、特別なハードウェア命令を使用します。これは、変数が使用されるたびにメインメモリからフェッチされることを意味する可能性があります。タイミングの違いは、この説明と一致しています。