さまざまなIntelプロセッサのlockcmpxchg命令の平均レイテンシに関するリファレンスを探しています。私はそのトピックに関する良い参考文献を見つけることができず、どんな参考文献も大いに役立つでしょう。
ありがとう。
さまざまなIntelプロセッサのlockcmpxchg命令の平均レイテンシに関するリファレンスを探しています。私はそのトピックに関する良い参考文献を見つけることができず、どんな参考文献も大いに役立つでしょう。
ありがとう。
非常に多くのバリエーションがあるため、これに関する適切なリファレンスは、あるとしてもほとんどありません。それは基本的にバス速度、メモリ速度、プロセッサ速度、プロセッサ数、周囲の命令、メモリフェンシング、そしておそらく月とエベレストの間の角度を含むすべてに依存します...
既知の(固定された)ハードウェア、オペレーティング環境、リアルタイムオペレーティングシステム、および排他的制御など、非常に特殊なアプリケーションがある場合は、それが問題になる可能性があります。この場合、ベンチマーク。ソフトウェアの実行場所をこのレベルで制御できない場合、測定は事実上無意味です。
これらの回答で説明されているように、ロックはCASを使用して実装されるため、ロックの代わりにCASを使用することができれば(少なくとも2つの操作が必要になります)、より高速になります(特に?おそらくのみ)。
見つけるのに最適なリファレンスはIntelSoftwareDeveloper's Manualsですが、バリエーションが非常に多いため、実際の数はわかりません。ただし、可能な限り最高のパフォーマンスを得る方法について説明します。おそらく、プロセッサーのデータシート(「テクニカルドキュメント」の下にあるi7 Extreme Editionのデータシートなど)には、実際の数値(または少なくとも範囲)が記載されています。
最高のx86命令レイテンシリファレンスは、さまざまなIntel / AMD / VIAチップでの実際の経験的測定に基づいており、市場に出回っている最新のCPU用に頻繁に更新されている、 Agnerの最適化マニュアルに含まれているものです。
残念ながら、CMPXCHG
命令レイテンシテーブルにリストされている命令は表示されませんが、4ページには次のように記載されています。
LOCKプレフィックスが付いた命令は、キャッシュ構成と場合によってはRAM速度に依存する長いレイテンシーを持ちます。複数のプロセッサまたはコアまたはダイレクトメモリアクセス(DMA)デバイスがある場合、ロックされたすべての命令は、RAMアクセスを伴う可能性のある排他的アクセスのためにキャッシュラインをロックします。LOCKプレフィックスは、シングルプロセッサシステムであっても、通常100クロックサイクル以上かかります。これは、メモリオペランドを使用するXCHG命令にも当てはまります。
私はここ数ヶ月、指数バックオフを検討してきました。
CASのレイテンシは、命令がキャッシュから動作できるかどうか、またはメモリから動作する必要があるかどうかによって完全に支配されます。通常、特定のメモリアドレスは、多数のスレッド(たとえば、キューへのエントリポインタ)によってCASされます。最新の成功したCASが、現在のCAS実行者とキャッシュを共有する論理プロセッサ(L1、L2、またはL3、もちろん高いレベルは低速ですが)によって実行された場合、命令はキャッシュで動作し、高速になります-a数サイクル。最新の成功したCASが、現在のエグゼキュータとキャッシュを共有しない論理コアによって実行された場合、最新のCASerの書き込みにより、現在のエグゼキュータのキャッシュラインが無効になり、メモリの読み取りが必要になります。数百サイクルかかります。
CASの動作自体は非常に高速で、数サイクルです。問題はメモリです。
AIDA64ソフトウェアを使用して、命令のレイテンシをチェックできます(ただし、どの命令をチェックするかをチェックすることはできません。ハードコードされた命令のリストがあります)。人々はhttp://instlatx64.atw.hu/で結果を公開しています
命令からlock
、AIDA64はlock add
命令を検証します(明示的なロックがなくてもxchg [mem]
常にロックprefix
されます)。
ここにいくつかの情報があります。また、比較のために、次の手順の待機時間を示します。
xchg reg1, reg2
これはロックされていません。add
レジスタとメモリに。ご覧のとおり、ロック命令は、Haswell-DTではロックされていないメモリストアよりもわずか5倍遅く、KabyLake-Sではわずか約2倍遅くなっています。
LOCK ADD [m8], r8 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
LOCK ADD [m16], r16 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
LOCK ADD [m32], r32 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
LOCK ADD [m32 + 8], r32 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
LOCK ADD [m64], r64 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
LOCK ADD [m64 + 16], r64 L: 5.96ns= 17.8c T: 7.21ns= 21.58c
XCHG r8, [m8] L: 5.96ns= 17.8c T: 7.21ns= 21.58c
XCHG r16, [m16] L: 5.96ns= 17.8c T: 7.21ns= 21.58c
XCHG r32, [m32] L: 5.96ns= 17.8c T: 7.21ns= 21.58c
XCHG r64, [m64] L: 5.96ns= 17.8c T: 7.21ns= 21.58c
ADD r32, 0x04000 L: 0.22ns= 0.9c T: 0.09ns= 0.36c
ADD r32, 0x08000 L: 0.22ns= 0.9c T: 0.09ns= 0.36c
ADD r32, 0x10000 L: 0.22ns= 0.9c T: 0.09ns= 0.36c
ADD r32, 0x20000 L: 0.22ns= 0.9c T: 0.08ns= 0.34c
ADD r8, r8 L: 0.22ns= 0.9c T: 0.05ns= 0.23c
ADD r16, r16 L: 0.22ns= 0.9c T: 0.07ns= 0.29c
ADD r32, r32 L: 0.22ns= 0.9c T: 0.05ns= 0.23c
ADD r64, r64 L: 0.22ns= 0.9c T: 0.07ns= 0.29c
ADD r8, [m8] L: 1.33ns= 5.6c T: 0.11ns= 0.47c
ADD r16, [m16] L: 1.33ns= 5.6c T: 0.11ns= 0.47c
ADD r32, [m32] L: 1.33ns= 5.6c T: 0.11ns= 0.47c
ADD r64, [m64] L: 1.33ns= 5.6c T: 0.11ns= 0.47c
ADD [m8], r8 L: 1.19ns= 5.0c T: 0.32ns= 1.33c
ADD [m16], r16 L: 1.19ns= 5.0c T: 0.21ns= 0.88c
ADD [m32], r32 L: 1.19ns= 5.0c T: 0.22ns= 0.92c
ADD [m32 + 8], r32 L: 1.19ns= 5.0c T: 0.22ns= 0.92c
ADD [m64], r64 L: 1.19ns= 5.0c T: 0.20ns= 0.85c
ADD [m64 + 16], r64 L: 1.19ns= 5.0c T: 0.18ns= 0.73c
LOCK ADD [m8], r8 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
LOCK ADD [m16], r16 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
LOCK ADD [m32], r32 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
LOCK ADD [m32 + 8], r32 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
LOCK ADD [m64], r64 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
LOCK ADD [m64 + 16], r64 L: 4.01ns= 16.8c T: 5.12ns= 21.50c
XCHG r8, [m8] L: 4.01ns= 16.8c T: 5.12ns= 21.50c
XCHG r16, [m16] L: 4.01ns= 16.8c T: 5.12ns= 21.50c
XCHG r32, [m32] L: 4.01ns= 16.8c T: 5.20ns= 21.83c
XCHG r64, [m64] L: 4.01ns= 16.8c T: 5.12ns= 21.50c
ADD r32, 0x04000 L: 0.33ns= 1.0c T: 0.12ns= 0.36c
ADD r32, 0x08000 L: 0.31ns= 0.9c T: 0.12ns= 0.37c
ADD r32, 0x10000 L: 0.31ns= 0.9c T: 0.12ns= 0.36c
ADD r32, 0x20000 L: 0.31ns= 0.9c T: 0.12ns= 0.36c
ADD r8, r8 L: 0.31ns= 0.9c T: 0.11ns= 0.34c
ADD r16, r16 L: 0.31ns= 0.9c T: 0.11ns= 0.32c
ADD r32, r32 L: 0.31ns= 0.9c T: 0.11ns= 0.34c
ADD r64, r64 L: 0.31ns= 0.9c T: 0.10ns= 0.31c
ADD r8, [m8] L: 1.87ns= 5.6c T: 0.16ns= 0.47c
ADD r16, [m16] L: 1.87ns= 5.6c T: 0.16ns= 0.47c
ADD r32, [m32] L: 1.87ns= 5.6c T: 0.16ns= 0.47c
ADD r64, [m64] L: 1.87ns= 5.6c T: 0.16ns= 0.47c
ADD [m8], r8 L: 1.89ns= 5.7c T: 0.33ns= 1.00c
ADD [m16], r16 L: 1.87ns= 5.6c T: 0.26ns= 0.78c
ADD [m32], r32 L: 1.87ns= 5.6c T: 0.28ns= 0.84c
ADD [m32 + 8], r32 L: 1.89ns= 5.7c T: 0.26ns= 0.78c
ADD [m64], r64 L: 1.89ns= 5.7c T: 0.33ns= 1.00c
ADD [m64 + 16], r64 L: 1.89ns= 5.7c T: 0.24ns= 0.73c
私はNOPの観点からCASとDCASのベンチマークを試みてきました。
いくつかの結果がありますが、まだ信頼していません。検証は進行中です。
現在、CAS / DCAS3/5NOP用のCorei5が表示されています。Xeonでは、20/22が表示されます。
これらの結果は完全に正しくない可能性があります-警告されました。