私のアーキテクチャ クラスでは、L1 キャッシュ ヒットは 1 サイクル (つまり、レジスタ アクセス時間と同じ) であると仮定したことを覚えていますが、最新の x86 プロセッサでは実際にそうでしょうか?
L1 キャッシュ ヒットには何サイクルかかりますか? 登録アクセスと比べてどうですか?
私のアーキテクチャ クラスでは、L1 キャッシュ ヒットは 1 サイクル (つまり、レジスタ アクセス時間と同じ) であると仮定したことを覚えていますが、最新の x86 プロセッサでは実際にそうでしょうか?
L1 キャッシュ ヒットには何サイクルかかりますか? 登録アクセスと比べてどうですか?
これは、このテーマに関するすばらしい記事です。
http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/1
あなたの質問に答えるために-はい、キャッシュヒットはレジスタアクセスとほぼ同じコストがかかります。そしてもちろん、キャッシュミスは非常にコストがかかります;)
PS:
詳細は異なりますが、このリンクにはいくつかの優れた球場の数字があります。
さまざまなキャッシュとメインメモリにアクセスするためのおおよそのコストは?
Core i7 Xeon 5500 Series Data Source Latency (approximate)
L1 CACHE hit, ~4 cycles
L2 CACHE hit, ~10 cycles
L3 CACHE hit, line unshared ~40 cycles
L3 CACHE hit, shared line in another core ~65 cycles
L3 CACHE hit, modified in another core ~75 cycles remote
L3 CACHE ~100-300 cycles
Local DRAM ~30 ns (~120 cycles)
Remote DRAM ~100 ns
PPS:
これらの数値は、はるかに古くて遅いCPUを表していますが、比率は基本的に次のようになります。
http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/2
Level Access Time Typical Size Technology Managed By
----- ----------- ------------ --------- -----------
Registers 1-3 ns ?1 KB Custom CMOS Compiler
Level 1 Cache (on-chip) 2-8 ns 8 KB-128 KB SRAM Hardware
Level 2 Cache (off-chip) 5-12 ns 0.5 MB - 8 MB SRAM Hardware
Main Memory 10-60 ns 64 MB - 1 GB DRAM Operating System
Hard Disk 3M - 10M ns 20 - 100 GB Magnetic Operating System/User
スループットとレイテンシーは別物です。サイクル コストを単純に加算することはできません。スループットについては、最近の CPU アーキテクチャ世代のサイクルあたりのロード/ストア-最新のマイクロアーキテクチャのクロックスループットあたり 2 ロードを参照してください。そして、キャッシュはどのように高速になるのでしょうか? を参照してください。ロード/ストア実行ユニットのマイクロアーキテクチャの詳細については、追跡できるメモリ レベルの並列処理の量を制限するロード/ストア バッファーの表示を含めます。この回答の残りの部分では、ポインターの追跡 (リンクされたリストやツリーなど) を含むワークロードに関連する レイテンシー と、アウトオブオーダー exec を非表示にする必要があるレイテンシーのみに焦点を当てます。(通常、L3 キャッシュ ミスは長すぎて完全に隠すことができません。)
シングル サイクルのキャッシュ レイテンシは、低いクロック速度の単純な順序パイプライン(したがって、各サイクルはよりナノ秒) で問題でした。たとえば、 MIPS I のような古典的な 5 ステージ RISC パイプラインは、キャッシュ ヒットでのメモリ アクセスに 1 サイクルを想定し、EX でのアドレス計算と、WB の前の 1 つの MEM パイプライン ステージでのメモリ アクセスを想定しています。
最新の高性能 CPU は、パイプラインをより多くのステージに分割し、各サイクルを短縮します。add
これにより、 //のような単純な命令を非常に高速に実行でき、1 サイクルのレイテンシでも高いクロック速度で実行or
できます。and
サイクルカウントとアウトオブオーダー実行の詳細については、Agner Fog の microarch pdfと、 x86 タグ wikiの他のリンクを参照してください。
Intel Haswell の L1 ロード使用レイテンシーは、最新の x86 CPU の典型であるポインター追跡で 4 サイクルです。mov eax, [eax]
つまり、それ自体を指すポインターを使用して、ループ内でどれだけ速く実行できるかです。(または、キャッシュにヒットするリンクされたリストの場合、閉ループで簡単にマイクロベンチを実行できます)。base+offset が base とは異なるページにある場合、ペナルティはありますか? も参照してください。この 4 サイクルのレイテンシの特別なケースは、ポインタが別のロードから直接来る場合にのみ適用され、それ以外の場合は 5 サイクルです。
Intel CPU の SSE/AVX ベクトルでは、ロード使用レイテンシが 1 サイクル高くなります。
ストア リロード レイテンシは 5 サイクルであり、キャッシュ ヒットまたはキャッシュ ミスとは関係ありません (これはストア フォワーディングであり、L1d キャッシュにまだコミットされていないストア データをストア バッファーから読み取ります)。
harold がコメントしたように、レジスタ アクセスは 0 サイクルです。たとえば、次のようになります。
inc eax
レイテンシは 1 サイクル (ALU 演算のみ)add dword [mem], 1
dword [mem]
からのロードの準備が整うまで 6 サイクルのレイテンシがあります。(ALU + 店舗転送)。たとえば、メモリにループ カウンターを保持すると、ループは 6 サイクルごとに 1 回の反復に制限されます。mov rax, [rsi]
rsi
準備ができてから L1 ヒットで準備が整うまでに4 サイクルのレイテンシがありrax
ます (L1 ロード使用レイテンシ)。http: / )。
Intel i7-4770 (Haswell)、3.4 GHz (ターボ ブースト オフ)、22 nm。RAM: 32 GB (PC3-12800 cl11 cr2)。
L1 データ キャッシュ = 32 KB、64 B/ライン、8 ウェイ。
L1 命令キャッシュ = 32 KB、64 B/ライン、8 ウェイ。
L2 キャッシュ = 256 KB、64 B/ライン、8 ウェイ
L3 キャッシュ = 8 MB、64 B/ライン
L1 データ キャッシュ レイテンシ = ポインターを介した単純なアクセスの場合は 4 サイクル (
mov rax, [rax]
)L1 データ キャッシュ レイテンシ = 複雑なアドレス計算を伴うアクセスの場合は 5 サイクル (
mov rax, [rsi + rax*8]
)。L2 キャッシュのレイテンシ = 12 サイクル
L3 キャッシュ遅延 = 36 サイクル
RAM レイテンシ = 36 サイクル + 57 ns
最上位のベンチマーク ページはhttp://www.7-cpu.com/utils.htmlですが、テスト サイズの違いが何を意味するのかはまだ実際には説明されていませんが、コードは利用可能です。テスト結果には、このテストの Haswell とほぼ同じSkylakeが含まれています。
@ paulsm4の回答には、いくつかのリモート(他のソケット)メモリ/ L3番号を含むマルチソケットNehalem Xeonの表があります。
私が正しく覚えていれば、それは約1〜2クロックサイクルですが、これは推定値であり、新しいキャッシュの方が高速である可能性があります。これは私が持っているコンピュータアーキテクチャの本からのものであり、これはAMDの情報であるため、Intelはわずかに異なる可能性がありますが、5〜15クロックサイクルに制限します。
編集:おっとL2はTAGアクセスで10サイクル、L1は1〜2サイクルかかります、私の間違い:\
実際、L1 キャッシュ ヒットのコストは、レジスタ アクセスのコストとほぼ同じです。これは私にとっては驚きでしたが、少なくとも私のプロセッサー (Athlon 64) にとってはそうです。しばらく前に、マルチプロセッサ システムでの共有データへのアクセス効率をベンチマークする簡単なテスト アプリケーションを作成しました。アプリケーション本体は、定義済みの期間中に増加する単純なメモリ変数です。比較を行うために、最初に非共有変数のベンチマークを行いました。そして、その活動中に結果をキャプチャしましたが、アプリケーションの逆アセンブル中に、コンパイラが期待を裏切り、不要な最適化をコードに適用していることに気付きました。変数をCPUレジスタに入れ、メモリアクセスなしでレジスタ内で繰り返しインクリメントします。しかし、レジスター変数の代わりにインメモリー変数を使用するようにコンパイラーに強制した後、本当に驚きました。更新されたアプリケーションでは、ほぼ同じベンチマーク結果が得られました。パフォーマンスの低下はごくわずか (~1 ~ 2%) で、何らかの副作用に関連しているように見えます。
結果:
1) L1 キャッシュは、管理されていないプロセッサ レジスタ プールと見なすことができると思います。
2) プロセッサ レジスタ内のデータに頻繁にアクセスするコンパイラ ストアを強制することによって、残忍なアセンブリ最適化を適用する意味はありません。それらが非常に頻繁にアクセスされる場合、それらは L1 キャッシュに存在するため、プロセッサ レジスタと同じアクセス コストが発生します。