web-dev-qa-db-ja.com

ほとんどのプロセッサで、L1キャッシュのサイズがL2キャッシュのサイズよりも小さいのはなぜですか?

ほとんどのプロセッサで、L1キャッシュのサイズがL2キャッシュのサイズよりも小さいのはなぜですか?

30

その理由はいくつかあります。

L2はシステムに存在し、L1キャッシュミスが発生した場合の速度を上げます。 L1のサイズがL2のサイズと同じかそれよりも大きい場合、L2はL1よりも多くのキャッシュラインに対応できず、L1キャッシュミスを処理できません。設計/コストの観点から、L1キャッシュはプロセッサにバインドされており、L2より高速です。キャッシュの全体的な考え方は、最も遅いハードウェアよりもパフォーマンスが高く(かつ高価)、しかもより高速なハードウェアよりも安価な中間ハードウェアを追加することで、遅いハードウェアへのアクセスを高速化することです。 L1キャッシュを2倍にすることにした場合でも、L2をインクリメントして、L1キャッシュミスを高速化します。

では、なぜL2キャッシュがまったく存在するのでしょうか。まあ、L1キャッシュは通常、パフォーマンスが高く、構築コストが高く、シングルコアにバインドされています。つまり、L1サイズを一定量増やすと、そのコストはデュアルコアプロセッサでは4倍、クアッドコアでは8倍になります。 L2は通常、異なるコアで共有されます-アーキテクチャーによっては、プロセッサーのカップルまたはすべてのコアで共有できるため、L1とL2の価格が同じであっても、L2を増やすコストは小さくなります-そうではない。

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はオンチップ帯域幅フィルターの役割を果たします。つまり、L2はオンチップ相互接続とL3へのアクセスを削減します。これにより、設計者は、リングのような低帯域幅の相互接続、および低速のシングルポートL3を使用して、L3を大きくすることができます。

おそらく、ポート数はキャッシュが消費するチップ領域の量に影響を与えるため、非常に重要な設計ポイントであることを言及する価値があります。ポートはキャッシュに配線を追加し、チップ領域と電力を大量に消費します。

45
Aater Suleman

@ Aaterの回答は、いくつかの基本を説明しています 。サイズだけでなく、レイテンシやその他のプロパティも含めて、詳細とIntel HaswellとAMD Piledriverの実際のキャッシュ構成の例を追加します。

IvyBridgeの詳細については、アドレスの計算時間を含む全体の負荷使用待ち時間、およびその間のデータバスの幅についての説明とともに、 「キャッシュを高速にするにはどうすればよいですか?」に対する私の回答 を参照してください。異なるレベルのキャッシュ。


L1は、very高速(レイテンシとスループット)である必要があります。これは、ヒット率が制限されていることを意味します。 L1dは、ほぼすべてのアーキテクチャで シングルバイトストア をサポートする必要があり、(一部の設計では)非境界整列アクセスもサポートする必要があります。これにより、ECC(エラー修正コード)を使用してデータを保護することが困難になり、実際には一部のL1d設計(インテル)はパリティーのみを使用し、ECCを実行できるキャッシュ(L2/L3)の外部レベルでのみより良いECCを使用します大きなチャンクでオーバーヘッドを削減します。

最新の平均リクエストレイテンシ(すべてのヒットとミスの平均)を低くできる単一レベルのキャッシュを設計することは不可能です マルチレベルキャッシュ。最近のシステムには、非常に空腹のコアが複数あり、すべて同じ比較的遅延の大きいDRAMへの接続を共有しているため、これは不可欠です。

すべてのコアには速度のために独自のプライベートL1が必要ですが、通常、少なくとも最後のレベルのキャッシュは共有されるため、複数のスレッドから同じデータを読み取るマルチスレッドプログラムは、各コアでDRAMにアクセスする必要はありません。 (そして、1つのコアによって書き込まれ、別のコアによって読み取られるデータのバックストップとして機能します)。 これは、まともなマルチコアシステムのために少なくとも2つのレベルのキャッシュを必要とし、、現在の設計における2つ以上のレベルの動機の一部です。最新のマルチコアx86 CPUは、各コアに高速の2レベルキャッシュがあり、すべてのコアで共有されるより低速でより大きなキャッシュを備えています。

L1ヒット率は依然として非常に重要です。L1キャッシュは、ヒット率が低下するため、可能な限り小さく/シンプル/高速ではありません。したがって、同じ全体的なパフォーマンスを実現するには、より高いレベルのキャッシュを高速にする必要があります。より高いレベルでより多くのトラフィックを処理する場合、それらのレイテンシは平均レイテンシのより大きなコンポーネントであり、より頻繁にスループットにボトルネックになります(またはより高いスループットが必要になります)。

多くの場合、高スループットとは、サイクルごとに複数の読み取りと書き込み、つまり複数のポートを処理できることを意味します。これは、低スループットキャッシュと同じ容量でより多くの領域と消費電力を必要とするため、L1が小さいままでいるもう1つの理由です。


L1は、それよりも大きい場合には機能しない速度のトリックも使用します。つまり、ほとんどのデザインは Virtually-Indexed、Physically Tagged(VIPT) L1を使用しますが、すべてのインデックスビットはページオフセットの下から来るため、PIPTのように動作します(仮想アドレスの下位ビットが物理アドレスと同じです)。これは synonyms/homonyms (誤ったヒットまたは同じデータがキャッシュに2回存在すること、およびリンクされた質問に対するPaul Claytonの詳細な回答を参照)を回避しますが、ヒット/ミスチェックの一部を並行して実行できますTLBルックアップ。 VIVTキャッシュはTLBを待つ必要はありませんが、ページテーブルが変更されるたびに無効にする必要があります。

X86(4kiBの仮想メモリページを使用)では、32kiBの8ウェイ連想L1キャッシュが現代の設計では一般的です。 8つのタグは仮想アドレスの下位12ビットに基づいてフェッチできます。これらのビットは仮想アドレスと物理アドレスで同じであるためです(4kiBページのページオフセットの下にあります)。このL1キャッシュの高速ハックは、インデックスがTLBの結果に依存しないほど十分に小さく、関連付けられている場合にのみ機能します。 32kiB/64Bライン/ 8ウェイ関連性= 64(2 ^ 6)セット。したがって、アドレスの最下位6ビットは行内のバイトを選択し、次の6ビットindexは8つのタグのセットです。この8個のタグのセットはTLBルックアップと並行してフェッチされるため、TLB結果の物理ページ選択ビットに対してタグを並行してチェックし、キャッシュの8つの方法のどれか(存在する場合)がデータを保持するかどうかを判断できます。 。

より大きなL1キャッシュを作成することは、タグのフェッチを開始してパラレルコンパレーターにロードする前にTLBの結果を待つか、log2(sets)+ log2(line_size)を維持するために連想性を高める必要があることを意味します<= 12.(関連性が高いほど、セットあたりのウェイ数が増える=>セットの総数が少ない=インデックスビットが少ない)。したがって、たとえば64kiBキャッシュは16ウェイアソシアティブである必要があります。それでも64セットですが、各セットには2倍の数のウェイがあります。これにより、L1サイズを現在のサイズよりも大きくすると、電力、および場合によってはレイテンシの観点からも非常に高価になります。

L1Dキャッシュロジックに多くの電力バジェットを費やすと、順不同の実行、デコード、そしてもちろんL2キャッシュなどに使用できる電力が少なくなります。コア全体を4GHzで実行し、溶融することなく(高ILPコードで)クロックあたり約4命令を維持するには、バランスの取れた設計が必要です。この記事を参照してください: 最新のマイクロプロセッサ:90分ガイド!

キャッシュが大きいほど、フラッシュによる損失が大きくなるため、大規模なVIVT L1キャッシュは、現在のVIPTのように機能するPIPTよりも劣ります。また、L1Dが大きくても待機時間が長くなると、おそらくさらに悪くなります。

@ PaulClaytonによると 、L1キャッシュは多くの場合、タグと並行してセット内のすべてのdataをフェッチするため、正しいときに選択する準備ができています。タグが検出されました。これを行うための電力コストは関連性に比例するため、大きな関連性の高いL1は、電力使用とダイ領域(およびレイテンシ)に本当に悪影響を及ぼします。 (L2やL3と比較すると、それほど多くの領域はありませんが、物理的な近接はレイテンシにとって重要です。光の速度の伝搬遅延は、クロックサイクルが1/4ナノ秒の場合に重要です。)

低速のキャッシュ(L3など)は、低い電圧/クロック速度で実行して、発熱を抑えることができます。さらに、ストレージセルごとに異なるトランジスタ配置を使用して、高速よりも電力に対して最適化されたメモリを作成することもできます。

マルチレベルキャッシュには、電力使用に関連する多くの理由があります。小さなチップの冷却は難しいので、電力/熱は最近のCPU設計で最も重要な制約の1つです。すべては、速度とパワー(および/またはダイ領域)の間のトレードオフです。また、多くのCPUはバッテリーで駆動されているか、追加の冷却が必要なデータセンターにあります。


L1はほとんどの場合、個別の命令キャッシュとデータキャッシュに分割されます。コードフェッチをサポートする統合L1の追加の読み取りポートの代わりに、別のI-TLBに関連付けられた別のL1Iキャッシュ。 (最新のCPUには、通常L2 I-TLBとD-TLBによって共有される変換用の2番目のレベルのキャッシュであるL2-TLBがあり、通常のL2キャッシュで使用されるTLBではありません)。これにより、合計合計64kiBのL1キャッシュが静的にコードとデータキャッシュに分割され、同じ合計スループットを持つモンスター64k L1統合キャッシュよりもはるかに安価(そしておそらくレイテンシが低く)なります。通常、コードとデータのオーバーラップはほとんどないため、これは大きな利点です。

L1Iは物理的にコードフェッチロジックの近くに配置でき、L1Dは物理的にロード/ストアユニットの近くに配置できます。クロックサイクルがナノ秒の3分の1しか続かない場合、光速の伝送ライン遅延は大きな問題です。配線のルーティングも重要です。 Intel Broadwellはシリコンの上に銅の13層を持っています

スプリットL1は速度に大きく役立ちますが、統合L2が最良の選択です。一部のワークロードは非常に小さなコードを持っていますが、大量のデータを扱います。コードとデータに静的にパーティション化するのではなく、より高いレベルのキャッシュを統合して、さまざまなワークロードに適応させることは理にかなっています。 (たとえば、L2のほとんどすべてが、大きな行列乗算を実行している間はコードではなくデータをキャッシュします。それに対して、肥大化したC++プログラムを実行しているときに大量のコードをホットにするか、または複雑なアルゴリズムの効率的な実装(gccを実行しているなど) )。コードは、常にDMAを使用してディスクからメモリに読み込まれるだけでなく、データとしてコピーできます。


キャッシュには、未処理のミスを追跡するロジックも必要です(順不同の実行は、最初のミスが解決される前に新しい要求が生成され続ける可能性があるためです)。未処理のミスが多いということは、ミスのレイテンシをオーバーラップさせ、より高いスループットを実現することを意味します。ロジックを複製したり、L2のコードとデータの間で静的にパーティション分割したりするのは適切ではありません。

大容量の低トラフィックキャッシュも、プリフェッチロジックを配置するのに適しています。ハードウェアプリフェッチにより、すべてのコードがソフトウェアプリフェッチ命令を必要とせずに、配列のループなどのパフォーマンスを向上させることができます。 (SWプリフェッチはしばらくの間重要でしたが、HWプリフェッチャーは以前よりもスマートであるため、 lrich Drepperのその他の点では優れていますすべてのプログラマーがメモリについて知っておくべきこと は、多くのユースケースで古くなっています。)

低トラフィックの高レベルキャッシュは、通常のLRUの代わりに適応置換ポリシーを使用するなどの賢いことを実行するためのレイテンシを提供できます。 Intel IvyBridge以降のCPUがこれを行う 、ワーキングセットのキャッシュヒットがわずかに大きすぎるアクセスパターンに抵抗するキャッシュに収まるように。 (たとえば、一部のデータを同じ方向に2回ループするということは、おそらく再利用される直前に削除されることを意味します。)


実際の例:Intel Haswell出典: David Kanterのマイクロアーキテクチャー分析 および Agner Fogのテスト結果(microarch pdf) 。 Intelの最適化マニュアル( x86 タグwiki内のリンク)も参照してください。

また、私は別の回答を書きました: インテルコアi7プロセッサーで使用されているキャッシュマッピングテクニックはどれですか?

最新の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にサイクルごとに64Bを供給できます。実際のポート数は不明です。
  • L3:統合、共有(すべてのコアで)8MiB(クアッドコアi7の場合)。包括的(すべてのL2およびL1コアキャッシュの)。 12または16ウェイアソシアティブ。 レイテンシ= 34サイクル。キャッシュコヒーレンシのバックストップとして機能するため、変更された共有データはメインメモリに出入りする必要がありません。

別の実際の例:AMD Piledriver:(例:OpteronとデスクトップFX CPU)キャッシュラインのサイズは、IntelとAMDがいくつかのもう数年。主にAgner Fogのmicroarch pdfからコピーされたテキスト 私が見つけたいくつかのスライドからの追加情報付き 、およびライトスルーL1 + 4k書き込み結合キャッシュの詳細 AgnerのブログL1のみがWTであり、L2ではないというコメント を使用します。

  • L1I:64 kB、2ウェイ、1組のコア間で共有(AMDのSMDバージョンは、ハイパースレッディングよりも静的パーティションが多く、それぞれを呼び出します)コア。各ペアは、ベクトル/ FPUユニット、およびその他のパイプラインリソースを共有します。)
  • L1D:16 kB、4ウェイ、コアあたり。 レイテンシ= 3-4 c。 (ページオフセットの下のすべての12ビットがインデックスに引き続き使用されるため、通常のVIPTトリックが機能することに注意してください。)(スループット:クロックごとに2つの操作、そのうちの1つはストアです)。 Policy = Write-Through 、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キャッシュはコアごとに分離されているはずなので、何が起こっているのかはわかりません。

19
Peter Cordes

この種の質問に興味がある人のために、私の大学は コンピューターアーキテクチャ:定量的アプローチ および コンピューターの組織と設計:ハードウェア/ソフトウェアインターフェイス を推奨しています。もちろん、これに時間がない場合は、簡単な概要を Wikipedia で確認できます。

3
Ilia K.

これの主な理由は、L1キャッシュの方が高速であり、そのためより高価であることです。

2
basti

ここでの他の回答は、L1とL2がそのままのサイズになっている具体的および技術的な理由を示しています。それらの多くは特定のアーキテクチャの考慮事項を動機づけていますが、実際には必要ありません。(プライベート)キャッシュサイズの増加につながるアーキテクチャ上のプレッシャーコアから離れるにつれて、かなり普遍的であり、最初に複数のキャッシュを使用する理由と同じです。

3つの基本的な事実は次のとおりです。

  1. ほとんどのアプリケーションのメモリアクセスは、不均一な分布で、高度な時間的局所性を示します。
  2. 多種多様なプロセスと設計全体で、キャッシュサイズとキャッシュ速度(レイテンシとスループット)を互いにトレードオフできます。1
  3. キャッシュの各レベルには、設計とパフォーマンスのコストが増加します。

したがって、基本的なレベルでは、キャッシュのサイズを2倍にすることができるかもしれませんが、小さい方のキャッシュと比較して、1.4の遅延ペナルティが発生します。

したがって、それは最適化の問題になります。キャッシュの数とキャッシュの大きさはどれくらいですか。メモリアクセスがワーキングセットのサイズ内で完全に均一である場合、かなり大きなキャッシュが1つになるか、キャッシュがまったくなくなる可能性があります。ただし、アクセスは非常に不均一であるため、小さくて高速なキャッシュは、そのサイズに不均衡な多数のアクセスをキャプチャできます。

事実2が存在しない場合は、チップの他の制約内で非常に大きくて非常に高速なL1キャッシュを作成するだけで、他のキャッシュレベルは必要ありません。

ファクト3が存在しなかった場合、膨大な数の細かい「キャッシュ」が中央に配置され、速くて小さくなり、外側が遅くて大きくなるか、アクセス時間が変化する単一のキャッシュになる可能性があります。コアに最も近いパーツ。実際には、ルール3は、キャッシュの各レベルに追加のコストがかかることを意味するため、通常、量子化されたいくつかのレベルのキャッシュになります。2

その他の制約

これにより、キャッシュカウントとキャッシュサイズの決定を理解するための基本的なフレームワークが得られます。たとえば、Intel x86のページサイズは4Kで、L1キャッシュは [〜#〜] vipt [〜#〜] アーキテクチャを使用しています。 VIPTは、キャッシュのサイズをウェイの数で割った値を大きくすることはできないことを意味します 4 KiBより。したがって、6ダースのIntelデザインで使用される8ウェイL1キャッシュは、最大で4 KiB * 8 = 32 KiBになります。それがこれらのデザインのL1キャッシュのサイズとまったく同じであることはおそらく偶然ではありません。この制約がなかった場合、連想性が低いか、L1キャッシュが大きい(例:64 KiB、4方向)と考えられていた可能性があります。


1 もちろん、面積や電力など、トレードオフには他の要素も含まれますが、これらの要素を一定に保つことでサイズと速度のトレードオフが適用され、一定に保たれなくても基本的な動作は同じです。

2 このプレッシャーに加えて、ほとんどのL1設計と同様に、既知のレイテンシキャッシュにはスケジューリングの利点があります。アウトオブオーダースケジューラは、L1キャッシュが返すサイクルのメモリ負荷に依存する操作を楽観的に送信できます。バイパスネットワークからの結果。これにより、競合が減少し、クリティカルパスからのレイテンシのサイクルが削減される可能性があります。これにより、最も内側のキャッシュレベルにある程度の圧力がかかり、レイテンシが均一または予測可能になり、おそらくキャッシュレベルが少なくなります。

原則として、この制限なしでVIPTキャッシュを使用できますが、これはOSサポート(たとえば、ページの色付け)を必要とするか、その他の制約がある場合のみです。 x86 Archはそれを行っておらず、おそらく今は起動できません。

1
BeeOnRope