ストリーミング SIMD 拡張命令の組込み関数のプロトタイプは、ヘッダファイル xmmintrin.h 内にあります。
void _mm_pause(void)
プロセッサに固有の時間の間、次の命令の実行を遅らせます。この命令を実行しても、アーキテクチャ上の状態は変化しません。この組込み関数を使用すると、パフォーマンスが大きく向上します。この組込み関数については、以降で詳しく説明します。
PAUSE 組込み関数
PAUSE 組込み関数は、ダイナミック・エグゼキューション (特に、アウトオブオーダー実行) をサポートするプロセッサ上で、spin-wait ループに使用します。spin-wait ループ内で PAUSE を使用すると、ロックの解放を検出するコードの処理速度が向上します。動的スケジューリングに PAUSE 命令を使用すると、スピンループの終了時のペナルティが軽減されます。
PAUSE 命令を使用したループの例
spin_loop:pause cmp eax, A jne spin_loop |
上の例では、メモリ・ロケーション A がレジスタ eax の値と一致するまで、プログラムはスピンします。次のコード・シーケンスは、test-and-test-and-set 操作を示しています。この例では、ロックの取得に失敗した場合にのみ、スピンが発生します。
get_lock: mov eax, 1 xchg eax, A ; Try to get lock cmp eax, 0 ; Test if successful jne spin_loop |
クリティカル・セクション
// critical_section code mov A, 0 ; Release lock jmp continue spin_loop: pause; // spin-loop hint cmp 0, A ; // check lock availability jne spin_loop jmp get_lock // continue: other code |
この例では、ロックの取得に成功すると予測して、最初の条件分岐は分岐せずに、そのままクリティカル・セクションの処理に移ります。すべての spin-wait ループに、PAUSE 命令を使用することを強くお勧めします。PAUSE は、既存のすべての IA-32 プロセッサで使用可能なため、プロセッサのタイプをテストする (CPUID テスト) 必要はありません。すべての従来のプロセッサは、PAUSE を NOP として実行しますが、PAUSE をヒントとして使用するプロセッサでは、パフォーマンスが大きく向上する可能性があります。