5

要約:少なくとも、ロードされた値がめったに変更されない場合は、ポインターを直接ロードするだけのパフォーマンスに近いとstd::atomic<int*>::load予想していました。std::memory_order_relaxedVisual Studio C ++ 2012の通常の負荷よりもアトミック負荷のパフォーマンスがはるかに悪いことがわかったので、調査することにしました。アトミックロードはコンペアアンドスワップループとして実装されていることがわかりましたが、これは可能な限り最速の実装ではないと思います。

質問std::atomic<int*>::load:コンペアアンドスワップループを実行する必要がある理由はありますか?

背景:MSVC ++ 2012は、このテストプログラムに基づいて、ポインターのアトミックロードでコンペアアンドスワップループを実行していると思います。

#include <atomic>
#include <iostream>

template<class T>
__declspec(noinline) T loadRelaxed(const std::atomic<T>& t) {
  return t.load(std::memory_order_relaxed);
}

int main() {
  int i = 42;
  char c = 42;
  std::atomic<int*> ptr(&i);
  std::atomic<int> integer;
  std::atomic<char> character;
  std::cout
    << *loadRelaxed(ptr) << ' '
    << loadRelaxed(integer) << ' '
    << loadRelaxed(character) << std::endl;
  return 0;
}

__declspec(noinline)アトミックロードに関連するアセンブリ命令を分離するために関数を使用しています。新しいMSVC++2012プロジェクトを作成し、x64プラットフォームを追加し、リリース構成を選択し、デバッガーでプログラムを実行して、逆アセンブリを確認しました。std::atomic<char>とパラメータの両方std::atomic<int>が同じ呼び出しを行うことにloadRelaxed<int>なります-これはオプティマイザが行ったことである必要があります。呼び出される2つのloadRelaxedインスタンス化の分解は次のとおりです。

loadRelaxed<int * __ptr64>

000000013F4B1790  prefetchw   [rcx]  
000000013F4B1793  mov         rax,qword ptr [rcx]  
000000013F4B1796  mov         rdx,rax  
000000013F4B1799  lock cmpxchg qword ptr [rcx],rdx  
000000013F4B179E  jne         loadRelaxed<int * __ptr64>+6h (013F4B1796h)  

loadRelaxed<int>

000000013F3F1940  prefetchw   [rcx]  
000000013F3F1943  mov         eax,dword ptr [rcx]  
000000013F3F1945  mov         edx,eax  
000000013F3F1947  lock cmpxchg dword ptr [rcx],edx  
000000013F3F194B  jne         loadRelaxed<int>+5h (013F3F1945h)  

命令lock cmpxchgはアトミックコンペアアンドスワップであり、ここで、、、またはをアトミックにロードするためのコードがcharコンペアintアンドint*スワップループであることがわかります。また、このコードを32ビットx86用にビルドしましたが、その実装はまだに基づいていlock cmpxchgます。

質問std::atomic<int*>::load:コンペアアンドスワップループを実行する必要がある理由はありますか?

4

1 に答える 1

1

緩和されたアトミックロードにはコンペアアンドスワップが必要だとは思いません。結局、このstd :: atomicの実装は私の目的には使用できませんでしたが、それでもインターフェイスが必要だったので、MSVCのバリア組み込み関数を使用して独自のstd::atomicを作成しました。std::atomicこれは、私のユースケースのデフォルトよりも優れたパフォーマンスを発揮します。ここでコードを見ることができます。ロードとストアのすべての注文について、C++11仕様に実装されることになっています。ところで、GCC4.6はこの点で良くありません。GCC4.7についてはわかりません。

于 2012-11-04T15:08:56.060 に答える