35

スレッド実行制御に揮発性ブール値を何年も使用していますが、正常に機能しました

// 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分待って、あきらめました!

同じ効果memory_order_relaxedでフラグloadを使用してみました。store

私のプラットフォーム:

  • Windows764ビット
  • MinGW gcc 4.6.x

私が間違っているのは何ですか?

注意:volatileは変数をスレッドセーフにしないことを私は知っています。私の質問は揮発性についてではなく、なぜアトミックが途方もなく遅いのかについてです。

4

3 に答える 3

31

「OlafDietsche」のコード

 USE ATOMIC
 real   0m1.958s
 user   0m1.957s
 sys    0m0.000s

 USE VOLATILE
 real   0m1.966s
 user   0m1.953s
 sys    0m0.010s

GCCSMALLER4.7を使用している場合

http://gcc.gnu.org/gcc-4.7/changes.html

C ++ 11/C11メモリモデルを指定するアトミック操作のサポートが追加されました。これらの新しい__atomicルーチンは、既存の__sync組み込みルーチンを置き換えます。

アトミックサポートは、メモリブロックでも利用できます。メモリブロックがサポートされている整数型と同じサイズおよび配置である場合、ロックフリー命令が使用されます。ロックフリーをサポートしていないアトミック操作は、関数呼び出しとして残されます。ライブラリ関数のセットは、GCCアトミックwikiの「外部アトミックライブラリ」セクションで入手できます。

そうそう..唯一の解決策はGCC4.7にアップグレードすることです

于 2012-10-30T11:35:27.417 に答える
13

これに興味があるので、Ubuntu 12.04、AMD 2.3 GHz、gcc4.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.000ssys0m0.004s

  • volatile bool

    $ time ./a.out
    real 0m1.413s
    user 0m1.368s
    sys 0m0.008s

  • std::atomic<bool>

    $ time ./a.out
    real 0m32.550s
    user 0m32.466s
    sys 0m0.008s

  • std::atomic<int>

    $ time ./a.out
    real 0m32.091s
    user 0m31.958s
    sys 0m0.012s

于 2012-10-30T11:23:14.893 に答える
1

私の推測では、これはハードウェアの問題だと思います。volatileを書くときは、変数について何も想定しないようにコンパイラーに指示しますが、私が理解しているように、ハードウェアはそれを通常の変数として扱います。これは、変数が常にキャッシュにあることを意味します。アトミックを使用する場合、特別なハードウェア命令を使用します。これは、変数が使用されるたびにメインメモリからフェッチされることを意味します。タイミングの違いは、この説明と一致しています。

于 2012-12-17T14:23:52.170 に答える