13

インラインアセンブリは64ビットコードのVC++2010でサポートされていないためpause、コードにx86-64命令を取り込むにはどうすればよいですか?__rdtsc()他の多くの一般的な組み立て手順(たとえば、、、など)のように、これに固有のものはないよう__cpuid()です。

理由としては、ビジーウェイトのユースケースに役立つ命令が必要です。これにより、(ハイパースレッドの)CPUを、そのCPUで実行されている他のスレッドで使用できるようになります( intel.comのPerformance Insightsを参照)。このpause命令は、このユースケースとスピンロックの実装に非常に役立ちます。MSがそれを組み込みとして含めなかった理由を理解できません。

ありがとう

4

2 に答える 2

15

うわー、これは追跡するのが非常に難しい問題でしたが、他の誰かが x86-64pause命令を必要とする場合に備えて:

YieldProcessor()マクロはwindows.h、文書化されていない_mm_pause組み込み関数に展開され、最終的pauseに 32 ビットおよび 64 ビット コードの命令に展開されます。

ちなみに、これは完全に文書化されておらず、MSDN に表示されるYieldProcessor()の部分的な (そして VC++ 2010 のドキュメントでは正しくない) ものです。

以下は、YieldProcessor() マクロのブロックがコンパイルされるものの例です。

    19:     ::YieldProcessor();
000000013FDB18A0 F3 90                pause  
    20:     ::YieldProcessor();
000000013FDB18A2 F3 90                pause  
    21:     ::YieldProcessor();
000000013FDB18A4 F3 90                pause  
    22:     ::YieldProcessor();
000000013FDB18A6 F3 90                pause  
    23:     ::YieldProcessor();
000000013FDB18A8 F3 90                pause  

ちなみに、Nehalem アーキテクチャでは、一時停止命令ごとに平均で約 9 サイクルの遅延が発生するようです (つまり、3.3 GHz CPU では 3 ns)。

于 2011-04-29T14:56:15.653 に答える