ほとんどのプロセッサで、L1キャッシュのサイズがL2キャッシュのサイズよりも小さいのはなぜですか?
7 に答える
L1はCPUコアに非常に緊密に結合されており、すべてのメモリアクセスでアクセスされます(非常に頻繁に)。したがって、データを非常に高速に返す必要があります(通常はクロックサイクル内)。レイテンシとスループット(帯域幅)はどちらも、L1データキャッシュにとってパフォーマンスにとって重要です。(たとえば、4サイクルのレイテンシー、およびクロックサイクルごとにCPUコアによる2つの読み取りと1つの書き込みをサポートします)。この高いアクセス帯域幅をサポートするには、多くの読み取り/書き込みポートが必要です。これらのプロパティを使用して大規模なキャッシュを構築することは不可能です。したがって、設計者はそれを小さく保ちます。たとえば、今日のほとんどのプロセッサでは32KBです。
L2はL1ミスでのみアクセスされるため、アクセス頻度は低くなります(通常はL1の1/20)。したがって、L2のレイテンシーは高くなり(たとえば、10〜20サイクル)、ポート数が少なくなります。これにより、設計者はそれを大きくすることができます。
L1とL2は非常に異なる役割を果たします。L1を大きくすると、L1アクセスの待ち時間が長くなり、依存するすべてのロードが遅くなり、アウト・オブ・オーダーの実行が隠されにくくなるため、パフォーマンスが大幅に低下します。L1サイズはほとんど議論の余地がありません。
L2を削除した場合、L1ミスは次のレベル、たとえばメモリに移動する必要があります。これは、多くのアクセスがメモリにアクセスすることを意味します。これは、より多くのメモリ帯域幅が必要であることを意味しますが、これはすでにボトルネックになっています。したがって、L2を維持することは好ましいことです。
専門家は、L1をレイテンシーフィルター(L1ヒットの一般的なケースを高速化するため)と呼び、L2を帯域幅フィルターと呼びます。これはメモリ帯域幅の使用量を削減するためです。
注:引数を単純にするために、2レベルのキャッシュ階層を想定しています。今日のマルチコアチップの多くでは、すべてのコア間で共有されるL3キャッシュがありますが、各コアには独自のプライベートL1とおそらくL2があります。これらのチップでは、共有最終レベルキャッシュ(L3)がメモリ帯域幅フィルターの役割を果たします。L2は、オンチップ帯域幅フィルターの役割を果たします。つまり、オンチップ相互接続とL3へのアクセスを減らします。これにより、設計者はリングのような低帯域幅の相互接続と、低速のシングルポートL3を使用できるようになり、L3を大きくすることができます。
ポートの数は、キャッシュが消費するチップ領域の量に影響を与えるため、非常に重要な設計ポイントであることに言及する価値があります。ポートは、多くのチップ領域と電力を消費するキャッシュにワイヤを追加します。
それにはさまざまな理由があります。
L2は、L1キャッシュミスが発生した場合に高速化するためにシステムに存在します。L1のサイズがL2のサイズと同じかそれより大きい場合、L2はL1より多くのキャッシュラインに対応できず、L1キャッシュミスに対処できません。設計/コストの観点から、L1キャッシュはプロセッサにバインドされており、L2よりも高速です。キャッシュの全体的な考え方は、最も遅いハードウェアよりもパフォーマンスが高く(そして高価で)、高速のハードウェアよりも安価な中間ハードウェアを追加することで、より遅いハードウェアへのアクセスを高速化することです。L1キャッシュを2倍にすることにした場合でも、L2をインクリメントして、L1キャッシュミスを高速化します。
では、なぜL2キャッシュがあるのでしょうか。L1キャッシュは通常、パフォーマンスが高く、構築にコストがかかり、シングルコアにバインドされます。つまり、L1サイズを一定量増やすと、そのコストにデュアルコアプロセッサでは4倍、クアッドコアでは8倍になります。L2は通常、異なるコアで共有されます。アーキテクチャによっては、プロセッサ内の2つまたはすべてのコアで共有できるため、L1とL2の価格が同じであっても、L2を増やすコストは少なくなります。そうではない。
@Aaterの答えはいくつかの基本を説明しています。サイズだけでなく、レイテンシーやその他のプロパティを使用して、IntelHaswellとAMDPiledriverの実際のキャッシュ構成の詳細と例をいくつか追加します。
IvyBridgeの詳細については、「キャッシュをこれほど高速にするにはどうすればよいですか?」に関する私の回答を参照してください。、アドレス計算時間、および異なるレベルのキャッシュ間のデータバスの幅を含む、全体的な負荷使用遅延についての説明があります。
L1は、ヒットレートが制限されている場合でも、非常に高速(レイテンシとスループット)である必要があります。L1dは、ほとんどすべてのアーキテクチャでシングルバイトストアをサポートする必要があり、(一部の設計では)アラインされていないアクセスもサポートする必要があります。これにより、データを保護するためにECC(エラー訂正コード)を使用することが難しくなります。実際、一部のL1dデザイン(Intel)はパリティのみを使用し、ECCを実行できるキャッシュの外部レベル(L2 / L3)でのみECCを改善します。オーバーヘッドを低くするために、チャンクを大きくします。
最新のマルチレベルキャッシュの低い平均リクエストレイテンシ(すべてのヒットとミスの平均)を提供できる単一レベルのキャッシュを設計することは不可能です。最近のシステムには複数の非常に空腹のコアがあり、すべてが同じ比較的高遅延のDRAMへの接続を共有しているため、これは不可欠です。
すべてのコアには速度のために独自のプライベートL1が必要ですが、少なくとも最後のレベルのキャッシュは通常共有されるため、複数のスレッドから同じデータを読み取るマルチスレッドプログラムは、各コアでDRAMにアクセスする必要はありません。(そして、あるコアによって書き込まれ、別のコアによって読み取られるデータのバックストップとして機能します)。 これには、正常なマルチコアシステムに少なくとも2レベルのキャッシュが必要であり、現在の設計では2レベルを超える動機の一部です。最新のマルチコアx86CPUは、各コアに高速の2レベルのキャッシュがあり、すべてのコアで共有されるより大きな低速のキャッシュがあります。
L1ヒット率は依然として非常に重要であるため、L1キャッシュは、ヒット率が低下するため、可能な限り小さく/単純/高速ではありません。したがって、同じ全体的なパフォーマンスを達成するには、より高速にするために、より高いレベルのキャッシュが必要になります。より高いレベルがより多くのトラフィックを処理する場合、それらの遅延は平均遅延のより大きな要素であり、より頻繁にスループットのボトルネックになります(またはより高いスループットが必要になります)。
多くの場合、高スループットとは、サイクルごとに複数の読み取りと書き込み、つまり複数のポートを処理できることを意味します。これは、低スループットのキャッシュと同じ容量でより多くの領域と電力を必要とするため、L1が小さいままであるもう1つの理由です。
L1は、それが大きければ機能しないスピードトリックも使用します。つまり、ほとんどのデザインは仮想インデックス、物理タグ(VIPT) L1を使用しますが、すべてのインデックスビットはページオフセットの下から来るため、PIPTのように動作します(仮想アドレスの下位ビットは物理アドレスと同じであるため) 。これにより、同義語/同音異義語(誤ったヒットまたは同じデータがキャッシュに2回存在し、リンクされた質問に関するPaul Claytonの詳細な回答を参照)を回避できますが、ヒット/ミスチェックの一部をTLBルックアップと並行して実行できます。VIVTキャッシュはTLBを待つ必要はありませんが、ページテーブルが変更されるたびに無効にする必要があります。
x86(4kiB仮想メモリページを使用)では、32kiBの8ウェイアソシアティブL1キャッシュが最新のデザインで一般的です。8つのタグは、仮想アドレスの下位12ビットに基づいてフェッチできます。これは、これらのビットが仮想アドレスと物理アドレスで同じであるためです(4kiBページのページオフセットを下回っています)。このL1キャッシュのスピードハックは、インデックスがTLBの結果に依存しないほど十分に小さく、関連性がある場合にのみ機能します。32kiB /64Bライン/8方向の結合性=64(2 ^ 6)セット。したがって、アドレスの下位6ビットは行内のバイトを選択し、次の6ビットはインデックスを作成します8つのタグのセット。この8つのタグのセットはTLBルックアップと並行してフェッチされるため、タグをTLB結果の物理ページ選択ビットと並行してチェックして、キャッシュの8つの方法のどれがデータを保持しているかを判断できます。 。(PIPT L1キャッシュもVIPTであり、インデックスを物理に変換せずにセットにアクセスするための最小の関連付け)
より大きなL1キャッシュを作成するということは、タグのフェッチと並列コンパレータへのロードを開始する前にTLBの結果を待つ必要があるか、log2(sets)+ log2(line_size)を維持するために結合性を高める必要があることを意味します。 <= 12.(関連性が高いほど、セットあたりのウェイ数が多い=>合計セット数が少ない=インデックスビットが少ない)。したがって、たとえば64kiBキャッシュは16ウェイアソシアティブである必要があります。それでも64セットですが、各セットには2倍のウェイがあります。これにより、L1サイズを現在のサイズを超えて増やすと、電力、さらには遅延の点で非常にコストがかかります。
L1Dキャッシュロジックにより多くの電力バジェットを費やすと、アウトオブオーダー実行、デコード、そしてもちろんL2キャッシュなどに使用できる電力が少なくなります。コア全体を4GHzで実行し、(高ILPコードで)クロックあたり最大4命令を維持するには、バランスの取れた設計が必要です。この記事を参照してください:最新のマイクロプロセッサ:90分のガイド!。
キャッシュが大きいほど、フラッシュによって失われる量が増えるため、VIVT L1キャッシュが大きいと、現在のVIPT-that-works-like-PIPTよりも悪くなります。また、L1Dが大きくてもレイテンシが高い場合は、おそらくさらに悪くなります。
@PaulClaytonによると、L1キャッシュは、タグと並行してセット内のすべてのデータをフェッチすることが多いため、適切なタグが検出されると、すぐに選択できるようになります。これを行うための電力コストは関連性に比例するため、関連性の高い大きなL1は、電力使用とダイ領域(および遅延)に非常に悪影響を及ぼします。(L2およびL3と比較すると、それほど多くの領域はありませんが、遅延には物理的な近接性が重要です。光速の伝播遅延は、クロックサイクルが1/4ナノ秒の場合に重要です。)
低速のキャッシュ(L3など)は、より低い電圧/クロック速度で実行して、熱を少なくすることができます。また、ストレージセルごとに異なるトランジスタの配置を使用して、高速よりも電力用に最適化されたメモリを作成することもできます。
マルチレベルキャッシュには、電力使用に関連する多くの理由があります。小さなチップの冷却は難しいため、電力/熱は最新のCPU設計における最も重要な制約の1つです。すべてが速度とパワー(および/またはダイ領域)の間のトレードオフです。また、多くのCPUはバッテリーで動作するか、追加の冷却が必要なデータセンターにあります。
L1は、ほとんどの場合、個別の命令キャッシュとデータキャッシュに分割されます。 コードフェッチをサポートするための統合L1の追加の読み取りポートの代わりに、個別のI-TLBに関連付けられた個別のL1Iキャッシュを使用できます。(最近のCPUには多くの場合L2-TLBがあります。これは、通常のL2キャッシュで使用されるTLBではなく、L1 I-TLBとD-TLBで共有される変換用の第2レベルのキャッシュです)。これにより、合計64kiBのL1キャッシュがコードキャッシュとデータキャッシュに静的に分割され、同じ合計スループットのモンスター64k L1統合キャッシュよりもはるかに安価になります(おそらくレイテンシが低くなります)。通常、コードとデータの重複はほとんどないため、これは大きなメリットです。
L1Iは、コードフェッチロジックの物理的に近くに配置できますが、L1Dは、ロード/ストアユニットの物理的に近くに配置できます。光速伝送線路の遅延は、クロックサイクルがナノ秒の1/3しか続かない場合に大きな問題になります。配線の配線も重要です。たとえば、IntelBroadwellにはシリコンの上に13層の銅があります。
分割L1は速度に大いに役立ちますが、統合L2が最良の選択です。 一部のワークロードのコードは非常に小さいですが、大量のデータに影響を与えます。コードとデータに静的に分割するのではなく、高レベルのキャッシュを統合してさまざまなワークロードに適応させることは理にかなっています。(たとえば、L2のほとんどすべては、大きな行列乗算を実行している間はコードではなくデータをキャッシュしますが、肥大化したC ++プログラムを実行している間は大量のコードをホットにしたり、複雑なアルゴリズムの効率的な実装(gccの実行など)を実行したりします) )。コードはデータとしてコピーできますが、DMAを使用してディスクからメモリにロードするだけではありません。
キャッシュには、未解決のミスを追跡するロジックも必要です(アウトオブオーダー実行は、最初のミスが解決される前に新しいリクエストが生成され続ける可能性があるため)。未処理のミスが多いということは、ミスのレイテンシーをオーバーラップさせて、より高いスループットを実現することを意味します。L2でロジックを複製したり、コードとデータを静的に分割したりするのは適切ではありません。
より大きなトラフィックの少ないキャッシュも、プリフェッチロジックを配置するのに適した場所です。ハードウェアプリフェッチにより、すべてのコードにソフトウェアプリフェッチ命令を必要とせずに、配列をループするなどのパフォーマンスが向上します。(SWプリフェッチはしばらくの間重要でしたが、HWプリフェッチャーは以前よりも賢いので、Ulrich Drepperの優れた、すべてのプログラマーがメモリについて知っておくべきことのアドバイスは、多くのユースケースでは時代遅れです。)
トラフィックの少ない高レベルのキャッシュは、通常のLRUの代わりに 適応型置換ポリシーを使用するなどの巧妙な処理を実行するための遅延を許容できます。Intel IvyBridge以降のCPUはこれを実行し、キャッシュに収まらないほどわずかに大きいワーキングセットに対してキャッシュヒットが発生しないアクセスパターンに抵抗します。(たとえば、一部のデータを同じ方向に2回ループするということは、再利用される直前にデータが削除される可能性があることを意味します。)
実際の例:IntelHaswell。出典:DavidKanterのマイクロアーキテクチャ分析とAgnerFogのテスト結果(microarch pdf)。Intelの最適化マニュアル(x86タグwikiのリンク)も参照してください。
また、私は別の答えを書きました:どのキャッシュマッピング技術がIntel Corei7プロセッサで使用されていますか?
最新のIntel設計では、キャッシュコヒーレンストラフィックのバックストップとして、すべてのコアで共有される大規模な包括的L3キャッシュを使用しています。コア間で物理的に分散されており、コアあたり2048セット* 16ウェイ(2MiB)です(IvyBridge以降の適応型置換ポリシーを使用)。
キャッシュの下位レベルはコアごとです。
- L1:コアごとに32kiBの各命令とデータ(分割)、8ウェイアソシアティブ。 レイテンシー=4サイクル。少なくとも2つの読み取りポート+1つの書き込みポート。(L1とL2の間のトラフィックを処理するためのさらに多くのポート、またはL2からのキャッシュラインの受信がストアの廃止と競合する可能性があります。)10個の未処理のキャッシュミス(10個のフィルバッファー)を追跡できます。
- L2:統合されたコアごとの256kiB、8ウェイアソシアティブ。 レイテンシー=11または12サイクル。読み取り帯域幅:64バイト/サイクル。メインのプリフェッチロジックはL2にプリフェッチします。16の未解決のミスを追跡できます。L1IまたはL1Dに1サイクルあたり64Bを供給できます。実際のポート数は不明です。
- L3:統合、共有(すべてのコアで)8MiB(クアッドコアi7の場合)。(すべてのL2およびL1コアごとのキャッシュの)包括的。12または16ウェイアソシアティブ。 レイテンシー=34サイクル。キャッシュコヒーレンシのバックストップとして機能するため、変更された共有データをメインメモリに送信して戻す必要はありません。
もう1つの実際の例:AMD Piledriver:(OpteronやデスクトップFX CPUなど)キャッシュラインのサイズは、IntelやAMDが数年前から使用しているように、依然として64Bです。ほとんどがAgnerFogのmicroarchpdfからコピーされたテキストで、私が見つけたいくつかのスライドからの追加情報と、AgnerのブログのライトスルーL1 + 4k書き込み結合キャッシュの詳細と、L2ではなくL1のみがWTであるというコメントがあります。
- L1I:64 kB、双方向、コアのペア間で共有(AMDのバージョンのSMDは、ハイパースレッディングよりも静的なパーティション分割があり、それぞれをコアと呼びます。各ペアは、ベクター/ FPUユニットおよびその他のパイプラインリソースを共有します。)
- L1D:16 kB、4ウェイ、コアあたり。レイテンシー=3-4c。(ページオフセットより下の12ビットすべてが引き続きインデックスに使用されるため、通常のVIPTトリックが機能することに注意してください。)(スループット:クロックごとに2つの操作、そのうちの1つはストアです)。 ポリシー=ライトスルー、4kのライトコンバインキャッシュを使用。
- L2:2 MB、16ウェイ、2つのコア間で共有。レイテンシー=20クロック。4クロックごとに1つのスループットを読み取ります。12クロックごとに1つの書き込みスループット。
- L3:0〜8 MB、64ウェイ、すべてのコア間で共有。 レイテンシー=87クロック。15クロックごとに1つのスループットを読み取ります。21クロックあたり1の書き込みスループット
Agner Fogは、ペアの両方のコアがアクティブな場合、ペアの残りの半分がアイドル状態の場合よりもL1スループットが低くなると報告しています。L1キャッシュはコアごとに分離されていると想定されているため、何が起こっているのかはわかりません。
ここでの他の回答は、L1とL2のサイズがそのままである特定の技術的な理由を示しています。それらの多くは特定のアーキテクチャの考慮事項を動機付けていますが、実際には必要ありません。根本的なアーキテクチャの圧力が(プライベート)キャッシュサイズの増加につながります。コアから離れるにつれて、かなり普遍的であり、そもそも複数のキャッシュの理由と同じです。
3つの基本的な事実は次のとおりです。
- ほとんどのアプリケーションのメモリアクセスは、不均一な分布で高度な時間的局所性を示します。
- 多種多様なプロセスと設計にわたって、キャッシュサイズとキャッシュ速度(レイテンシーとスループット)は互いにトレードオフすることができます1。
- キャッシュの各レベルには、増分設計とパフォーマンスコストが含まれます。
したがって、基本的なレベルでは、キャッシュのサイズを2倍と言うことができるかもしれませんが、小さいキャッシュと比較して1.4のレイテンシペナルティが発生します。
したがって、それは最適化問題になります。キャッシュの数とサイズを増やす必要がありますか?メモリアクセスがワーキングセットサイズ内で完全に均一である場合、おそらく単一のかなり大きなキャッシュになるか、キャッシュがまったくなくなるでしょう。ただし、アクセスは非常に不均一であるため、小さくて高速なキャッシュは、そのサイズに不釣り合いな多数のアクセスをキャプチャできます。
ファクト2が存在しなかった場合は、チップの他の制約内に非常に大きく、非常に高速なL1キャッシュを作成するだけで、他のキャッシュレベルは必要ありません。
ファクト3が存在しなかった場合、中央では高速で小さく、外部では低速で大きく、アクセス時間が可変の単一のキャッシュである、非常に多くのきめ細かい「キャッシュ」が作成されます。コアに最も近いパーツ。実際には、ルール3は、キャッシュの各レベルに追加のコストがかかることを意味します。したがって、通常、キャッシュ2の量子化されたレベルがいくつかあります。
その他の制約
これにより、キャッシュ数とキャッシュサイズの決定を理解するための基本的なフレームワークが提供されますが、2番目の要素も機能します。たとえば、Intel x86のページサイズは4Kで、L1キャッシュはVIPTアーキテクチャを使用しています。VIPTは、キャッシュのサイズをウェイの数で割った値が4KiBより大きくならないことを意味します。したがって、半ダースのIntelデザインで使用される8ウェイL1キャッシュは、最大で4 KiB * 8 =32KiBになります。それがこれらのデザインのL1キャッシュのサイズとまったく同じであることはおそらく偶然ではありません。この制約がなかった場合は、結合性が低くなったり、L1キャッシュが大きくなったりする可能性があります(たとえば、64 KiB、4ウェイ)。
1もちろん、面積や電力など、トレードオフに関係する他の要因もありますが、これらの要因を一定に保つと、サイズと速度のトレードオフが適用され、一定に保たれなくても基本的な動作は同じです。
2このプレッシャーに加えて、ほとんどのL1設計と同様に、既知のレイテンシーのキャッシュにはスケジューリングの利点があります。また、アウトオブオーダースケジューラーは、L1キャッシュが返すサイクルのメモリ負荷に依存する操作を楽観的に送信できます。バイパスネットワークから結果を読み取ります。これにより、競合が減少し、クリティカルパスからの遅延のサイクルが短縮される可能性があります。これにより、最も内側のキャッシュレベルにある程度のプレッシャーがかかり、遅延が均一で予測可能になり、キャッシュレベルが少なくなる可能性があります。
3原則として、この制限なしでVIPTキャッシュを使用できますが、OSサポート(ページの色付けなど)を要求するか、他の制約がある場合に限ります。x86アーチはそれを行っておらず、おそらく今は開始できません。
この種の質問に興味がある人のために、私の大学はコンピュータアーキテクチャ:定量的アプローチとコンピュータの編成と設計:ハードウェア/ソフトウェアインターフェイスをお勧めします。もちろん、これを行う時間がない場合は、ウィキペディアで簡単な概要を入手できます。
これの主な理由は、L1-Cacheが高速であるため、より高価であるためだと思います。
https://en.wikichip.org/wiki/amd/microarchitectures/zen#Die
たとえば、AMD ZenコアのL1、L2、およびL3キャッシュの物理サイズを比較します。密度は、キャッシュレベルとともに劇的に増加します。
論理的には、質問はそれ自体に答えます。
L1がL2(結合)よりも大きい場合、L2キャッシュは必要ありません。
すべてをHDDに保存できるのに、なぜテープドライブに保存するのでしょうか。