3

共有変数に対して 2 つの操作を実行したいと考えています。アトミックに実行できることを保証する必要があります。次のアプローチが正しいかどうかを明確にするのに役立つ人がいます:

#include <atomic>
std::atomic<int> index;

void function()
{
     // I need the variable index to be incremented but bound in the 
     // range of [0,9].
     int loc_indx = index.load(std::memory_order_acquire);
     index.store( (loc_indx+1)%10  , std::memory_order_release);
}

私の理解では、インデックス ストア操作とインデックス ロード操作は一緒に実行する必要があります。ここの専門家の何人かは、上記のコードが次の擬似コードと同等になるかどうかを明確にすることができます:

ATOMIC
{
   index = (index+1)%10;
}

私は、Visual Studio 2012 の c++ 部分または/および 1.53 の boost::atomic 部分でアトミック パッケージを使用してきました。

4

1 に答える 1

4

アトミックの全体的な目的は、ロックと比較してパフォーマンスを向上させることです。

コードにロックはありません。memory_order列挙型は、コンパイラがコードを並べ替えないようにするためだけのものです(CPUがコードを並べ替えないようにするためでもありません)。これは、他のスレッドがloadとの間の値を変更する可能性がわずかにあることを意味しstoreます。保存された値が前の値に依存する必要がある場合、その間に行われた計算は無駄になり、やり直す必要があります。同時変更が実際に発生する可能性は低く、計算は安価で簡単なので、これを行うことはロックよりもかなり効率的です。

以前の値がわかっている場合は保存します。それ以外の場合は、再計算して再試行します。何かのようなもの:

 int loc_index = index.load(std::memory_order_acquire);
 int desired = (loc_index+1)%10;

 while ( !index.compare_exchange_strong( loc_index, desired ) )
 {
     desired = (loc_index+1)%10;
 }

compare_exchange_strongindexに格納されている値をloc_index;に比較する不可分操作です。それらが等しい場合、 ;に格納desiredされます。indexそれらが等しくない場合は、の値をにコピーしindexますloc_index。これは、に保存されている次の値が正しいことを確認するのに役立ちますindex

于 2013-02-27T18:57:12.110 に答える