コンピューティングおよびプロセッサ設計 において、変換ルックアサイドバッファ(TLB )は、仮想メモリアドレスから物理メモリアドレスへの最近の変換を格納するメモリキャッシュです。これは、ユーザー メモリ位置へのアクセスにかかる時間を短縮するために使用されます。[ 1 ]これはアドレス変換キャッシュとも呼ばれます。チップのメモリ管理ユニット(MMU)の一部です。TLB は、 CPUとCPU キャッシュの間、CPU キャッシュとメイン メモリの間、またはマルチレベル キャッシュの異なるレベルの間に配置される場合があります。デスクトップ、ラップトップ、およびサーバーのプロセッサの大部分は、メモリ管理ハードウェアに 1 つ以上の TLB を含んでおり、ページングまたはセグメント化された仮想メモリを使用するプロセッサにはほぼ必ず存在します。
TLB は、コンテンツ アドレス指定可能メモリ(CAM) として実装されることがあります。CAM の検索キーは仮想アドレスで、検索結果は物理アドレスです。要求されたアドレスが TLB に存在する場合、CAM 検索はすぐに一致し、取得した物理アドレスを使用してメモリにアクセスできます。これは TLB ヒットと呼ばれます。要求されたアドレスが TLB に存在しない場合はミスとなり、ページ テーブルを検索してページ ウォークと呼ばれるプロセスで変換が進みます。ページ ウォークは、複数のメモリ ロケーションの内容を読み取り、それらを使用して物理アドレスを計算する必要があるため、プロセッサの速度に比べて時間がかかります。ページ ウォークによって物理アドレスが決定された後、仮想アドレスから物理アドレスへのマッピングが TLB に入力されます。たとえば、 PowerPC 604は、データのロードとストア用に双方向セット アソシアティブTLB を備えています。[ 2 ]一部のプロセッサは、命令 TLB とデータ アドレス TLB が異なります。

TLBには、ページテーブルエントリとセグメントテーブルエントリを含む固定数のスロットがあります。ページテーブルエントリは仮想アドレスを物理アドレスと中間テーブルアドレスにマッピングし、セグメントテーブルエントリは仮想アドレスをセグメントアドレス、中間テーブルアドレス、およびページテーブルアドレスにマッピングします。仮想メモリは、プロセスから見たメモリ空間です。この空間は、多くの場合、固定サイズのページ(ページングメモリ)に分割されますが、あまり一般的ではありませんが、可変サイズのセグメント(セグメント化メモリ)に分割されます。ページテーブルは通常、メインメモリに格納され、仮想ページが物理メモリのどこに格納されているかを追跡します。この方式では、1バイトにアクセスするために2回のメモリアクセス(1回はページテーブルエントリ用、もう1回はバイト用)が必要です。まず、ページテーブルからフレーム番号を検索します。次に、ページオフセット付きのフレーム番号から実際のアドレスを取得します。したがって、単純な仮想メモリ方式では、メモリアクセス時間が2倍になるという影響が生じます。そのため、TLBはページテーブル方式でメモリ位置にアクセスする時間を短縮するために使用されます。 TLBはページテーブルのキャッシュであり、ページテーブルの内容のごく一部のみを表します。
物理メモリのアドレスを参照するTLBは、CPUとCPUキャッシュの間、CPUキャッシュと主記憶メモリの間、またはマルチレベルキャッシュの各レベル間に配置される場合があります。配置場所によって、キャッシュが物理アドレス指定を使用するか仮想アドレス指定を使用するかが決まります。キャッシュが仮想アドレス指定されている場合、要求はCPUからキャッシュに直接送信され、TLBはキャッシュミスが発生した場合にのみアクセスされます。キャッシュが物理アドレス指定されている場合、CPUはメモリ操作ごとにTLBルックアップを実行し、その結果得られた物理アドレスがキャッシュに送信されます。
ハーバードアーキテクチャまたは修正ハーバードアーキテクチャでは、命令とデータ用に別々の仮想アドレス空間またはメモリアクセスハードウェアが存在する場合があります。これにより、アクセスタイプごとに異なるTLB、命令変換ルックアサイドバッファ(ITLB)、およびデータ変換ルックアサイドバッファ(DTLB)が実現できます。データTLBと命令TLBを分離することで、さまざまな利点が実証されています。[ 4 ]
TLBは、高速なルックアップハードウェアキャッシュとして使用できます。図はTLBの動作を示しています。TLBの各エントリは、タグと値の2つの部分から構成されます。入力された仮想アドレスのタグがTLB内のタグと一致する場合、対応する値が返されます。TLBルックアップは通常、命令パイプラインの一部であるため、検索は高速で、パフォーマンスへの影響はほとんどありません。ただし、命令パイプライン内で検索できるようにするには、TLBのサイズを小さくする必要があります。
物理アドレス指定キャッシュの一般的な最適化手法は、キャッシュアクセスと並行してTLBルックアップを実行することです。仮想メモリ参照が行われるたびに、ハードウェアはTLBをチェックしてページ番号がTLB内に存在するかどうかを確認します。存在する場合はTLBヒットとなり、変換が行われます。フレーム番号が返され、メモリへのアクセスに使用されます。ページ番号がTLBに存在しない場合は、ページテーブルをチェックする必要があります。CPUによっては、これはハードウェアで自動的に行われるか、オペレーティングシステムへの割り込みを使用して行われます。フレーム番号が取得されると、それを使用してメモリにアクセスできます。さらに、ページ番号とフレーム番号をTLBに追加することで、次回の参照時に迅速に検索できるようになります。TLBが既に満杯の場合は、適切なブロックを選択して置き換える必要があります。置き換え方法には、LRU(Least Recently Used:最小使用頻度)、FIFO( First In, First Out:先入れ先出し)など、さまざまな方法があります。キャッシュとTLBに関連する仮想アドレス指定の詳細については、キャッシュに関する記事のアドレス変換のセクションを参照してください。

CPUは、命令キャッシュミス、データキャッシュミス、またはTLBミスが発生した場合、メインメモリにアクセスする必要があります。3番目のケース(最も単純なケース)は、目的の情報自体はキャッシュにあるものの、仮想メモリから物理メモリへの変換に必要な情報がTLBにない場合です。これらはすべて、メモリ階層の低速なレベルにアクセスする必要があるため、処理速度が遅くなります。そのため、TLBが正常に機能することが重要です。実際、TLBミスは、メインメモリからのロードだけでなく、ページウォークが必要となり、複数のメモリアクセスが発生するため、命令キャッシュミスやデータキャッシュミスよりもコストが高くなる可能性があります。
提供されたフローチャートは、TLB の動作を説明しています。TLB ミスの場合、CPU はページ テーブルで該当のエントリを確認します。現在ビットが設定されている場合、ページはメイン メモリにあり、プロセッサはページ テーブル エントリからフレーム番号を取得して物理アドレスを生成できます。[ 6 ]プロセッサは、新しいページ テーブル エントリを含めるように TLB も更新します。最後に、現在ビットが設定されていない場合、目的のページはメイン メモリになく、ページ フォルトが発行されます。その後、ページ フォルト割り込みが呼び出され、ページ フォルト処理ルーチンが実行されます。
ページワーキングセットがTLBに収まらない場合、TLBスラッシングが発生します。これは、頻繁にTLBミスが発生し、新しくキャッシュされたページがすぐに再び使用されるページを押し出すため、命令キャッシュやデータキャッシュのスラッシングとまったく同じようにパフォーマンスが低下する現象です。命令キャッシュやデータキャッシュのスラッシングが発生していなくても、TLBスラッシングが発生する可能性があります。これは、命令キャッシュとデータキャッシュが異なるサイズの単位でキャッシュされるためです。命令とデータはページ全体ではなく、小さなブロック(キャッシュライン)でキャッシュされますが、アドレス検索はページレベルで行われます。したがって、コードワーキングセットとデータワーキングセットがキャッシュに収まっていても、ワーキングセットが複数のページにまたがって断片化されている場合、仮想アドレスワーキングセットがTLBに収まらず、TLBスラッシングが発生する可能性があります。そのため、TLBの適切なサイズ設定には、対応する命令キャッシュとデータキャッシュのサイズだけでなく、それらが複数のページにまたがってどのように断片化されているかも考慮する必要があります。
キャッシュと同様に、TLBも複数のレベルを持つことができます。CPUは複数のTLBを備えて構築することが可能であり、現在ではそれが一般的です。例えば、非常に高速な小型のL1 TLB(完全連想方式の場合もあり)と、やや低速な大型のL2 TLBなどです。命令TLB(ITLB)とデータTLB(DTLB)が使用される場合、CPUは3つ(ITLB1、DTLB1、TLB2)または4つのTLBを持つことができます。
例えば、IntelのNehalem マイクロアーキテクチャは、4 KiB ページ用に 64 エントリ、2/4 MiB ページ用に 32 エントリを持つ 4 ウェイ セット アソシアティブ L1 DTLB 、 4 ウェイ アソシアティビティを使用する 4 KiB ページ用に 128 エントリ、2/4 MiB ページ用に 14 エントリの完全アソシアティブ L1 ITLB (ITLB の両部分は静的に 2 つのスレッドに分割) [ 7 ]、および 4 KiB ページ用に 512 エントリの統合 L2 TLB [ 8 ] を持ち、どちらも 4 ウェイ アソシアティブです。[ 9 ]
TLB によっては、小さなページと大きなページ用に別々のセクションがある場合があります。たとえば、Intel Skylake マイクロ アーキテクチャでは、1 GiB ページの TLB エントリと 4 KiB/2 MiB ページのTLB エントリが分離されています 。[ 10 ]
現代のアーキテクチャでは、TLBミスを処理するための3つの方式が用いられています。
MIPSアーキテクチャはソフトウェア管理のTLBを規定している。[ 12 ]
SPARC V9アーキテクチャでは、MMUなし、ソフトウェア管理TLBを備えたMMU、またはハードウェア管理TLBを備えたMMUの実装が可能であり[ 13 ]、UltraSPARCアーキテクチャ2005ではソフトウェア管理TLBが規定されている[ 14 ] 。
Itaniumアーキテクチャでは、ソフトウェア管理TLBまたはハードウェア管理TLBのいずれかを使用するオプションが提供されています。[ 15 ]
Alphaアーキテクチャはファームウェアで管理されるTLBを備えており、TLBミス処理コードはオペレーティングシステムではなくPALcodeにあります。プロセッサ用のPALcodeはプロセッサ固有かつオペレーティングシステム固有であるため、アーキテクチャでTLBフォーマットやTLBを制御する命令を指定する必要なく、異なるバージョンのPALcodeで異なるオペレーティングシステム向けに異なるページテーブルフォーマットを実装できます。[ 16 ]
これらはTLBの典型的なパフォーマンスレベルです。[ 17 ]
平均実効メモリサイクルレートは次のように定義されます。サイクルでははメモリ読み出しに必要なサイクル数です。はミス率であり、はヒット時間(サイクル単位)です。TLBヒットに1クロックサイクル、ミスに30クロックサイクル、メモリ読み出しに30クロックサイクルかかり、ミス率が1%の場合、実効メモリサイクル率は平均で(メモリアクセス1回あたり31.29クロックサイクル)。[ 18 ]
プロセス間のコンテキスト スイッチ(スレッド間ではない)で発生するようなアドレス空間の切り替えでは、仮想から物理へのマッピングが異なるため、一部の TLB エントリが無効になることがあります。これに対処する最も簡単な戦略は、TLB を完全にフラッシュすることです。つまり、切り替え後には TLB は空になり、メモリ参照はすべてミスになるため、フルスピードで動作するようになるまでにはしばらく時間がかかります。最新の CPU では、エントリがどのプロセス用であるかをマークするより効果的な戦略が採用されています。つまり、2 番目のプロセスが短時間だけ実行されて最初のプロセスに戻る場合、TLB には有効なエントリが残っている可能性があり、再ロードする時間を節約できます。[ 19 ]
コンテキストスイッチ時にTLBをフラッシュしないための他の戦略としては、(a)単一アドレス空間のオペレーティングシステムでは、すべてのプロセスに対して同じ仮想アドレスと物理アドレスのマッピングを使用する。(b) 一部のCPUにはプロセスIDレジスタがあり、ハードウェアは現在のプロセスIDと一致する場合にのみTLBエントリを使用する。
例えば、Alpha 21264では、各 TLB エントリにアドレス空間番号(ASN)がタグ付けされており、現在のタスクと一致する ASN を持つ TLB エントリのみが有効とみなされます。別の例として、Intel Pentium Proでは、レジスタCR4のページ グローバル イネーブル (PGE) フラグとページ ディレクトリまたはページ テーブル エントリのグローバル (G) フラグを使用して、タスク スイッチまたはレジスタ CR3 のロード時に、頻繁に使用されるページが TLB 内で自動的に無効化されるのを防ぐことができます。2010 のWestmere マイクロ アーキテクチャ以降、 Intel 64プロセッサは 12 ビットのプロセス コンテキスト識別子(PCID) もサポートしており、複数のリニア アドレス空間の TLB エントリを保持することができ、現在の PCID と一致するもののみがアドレス変換に使用されます。[ 20 ] [ 21 ]
ソフトウェア管理型TLBではTLBの選択的フラッシュが可能ですが、一部のハードウェアTLB(例えば、Intel 80386のTLB )では、アドレス空間スイッチ上でTLB全体をフラッシュするしか選択肢がありません。一方、他のハードウェアTLB(例えば、Intel 80486以降のx86プロセッサのTLB、およびARMプロセッサのTLB )では、仮想アドレスでインデックス付けされたTLBのエントリを個別にフラッシュできます。
TLB のフラッシュは、プロセス間でメモリを分離するための重要なセキュリティ メカニズムであり、あるプロセスが別のプロセスのメモリ ページに格納されているデータにアクセスできないようにします。メモリの分離は、特権を持つオペレーティングシステム カーネル プロセスとユーザー プロセス間の切り替え時に特に重要であり、これはMeltdownセキュリティ脆弱性によって強調されました。カーネル ページ テーブル分離(KPTI)などの緩和戦略は、パフォーマンスに影響を与える TLB フラッシュに大きく依存しており、PCID などのハードウェアで有効化された選択的 TLB エントリ管理から大きな恩恵を受けています。[ 22 ]
サーバー統合のための仮想化の出現に伴い、x86アーキテクチャの仮想化を容易にし、x86ハードウェア上での仮想マシンのパフォーマンスを向上させるために多くの努力がなされてきた。[ 23 ] [ 24 ]
通常、x86 TLB のエントリは特定のアドレス空間に関連付けられておらず、暗黙的に現在のアドレス空間を参照します。そのため、コンテキスト スイッチなどのアドレス空間の変更があるたびに、TLB 全体をフラッシュする必要があります。ソフトウェアで各 TLB エントリをアドレス空間に関連付けるタグを維持し、TLB ルックアップと TLB フラッシュ中にこのタグを比較することは、特に x86 TLB が非常に低いレイテンシで完全にハードウェアで動作するように設計されているため、非常にコストがかかります。2008 年に、Intel ( Nehalem ) [ 25 ]とAMD ( SVM ) [ 26 ]の両方が、TLB エントリの一部としてタグを導入し、ルックアップ中にタグをチェックする専用ハードウェアを導入しました。すべてのオペレーティングシステムがすぐにこれらのタグを完全に利用したわけではありませんが、Linux 4.14 では、特定の CPU で実行されているすべてのタスクに対して 12 ビットの PCID (4095 種類の値) では不十分であるため、最近使用されたアドレス空間を識別するためにタグの使用を開始しました。[ 27 ]
一致するTLBエントリが見つからない場合、TLBミス例外が発生します。
{{cite book}}: CS1メンテナンス: 場所 (リンク)