記事カテゴリトップ:AMBA CHIプロトコルについての勉強 - FPGA開発日記
AMBA CHIについて今更勉強している。
なんかググっているとなぜかGem5がCHIの解説ページを作っていた。イントロダクションを読んでみるとCHI Rubyプロトコルと言って厳密にはAMBA CHIとは異なるようなのだが、一応一通り読んでみても良さそうだ。
CHI rubyプロトコルは、MESIおよびMOESIのキャッシュ・コヒーレンシ・プロトコルをモデル化することを目的としている。 これは複数のキャッシュ階層について適用可能であり、Arm AMBA5 CHIプロトコルに基づいている。
CHIというのはCoherent Hub Interfaceのことで、要求はRN-F(リクエストノード)で発生し、SN-F(スレーブノード)で受け取る。 ICNはインターコネクトであり、CHIにおけるFull Coherent Home Nodes(HN-F)をカプセル化する役割を持つ。
HN-Fは、特定のアドレスに対するコヒーレンシ・ポイント(PoC)およびシリアライズ・ポイント(PoS)となる。
AMBA CHI使用自体では、非コヒーレント・リクエスタ(RN-I)および非コヒーレント・アドレス範囲(HN-IおよびSN-I)のために特定のタイプのノードを定義している。 Ruby CHIではIOアクセスはCHIを経由しないので、これをサポートしない。したがってRuby CHIではFull Coherent Node Typeのみを実装している。
プロトコルの概要
CHIプロトコル実装は、主に2つのコントローラーで構成されている:
Memory_Controller(src/mem/ruby/protocol/chi/CHI-mem.sm) : 実態はCHIスレーブノードCache_Controller(src/mem/ruby/protocol/chi/CHI-cache.sm): リクエスト・ノードとホーム・ノードの両方のキャッシュレベルをモデル化できる各リクエストタイプに対して設定可能なキャッシュブロックの割り当てと解除のポリシ
- リクエストの入力と出力のための、統合・分割選択可能なトランザクションバッファ
- MESIまたはMOESI操作
- ディレクトリとキャッシュタグとデータ配列のストール。
- リクエスト処理フローの複数のステップで待ち時間を注入するパラメータ。これにより、パフォーマンスをより綿密に較正することができる。
CHIの実装では、以下のキャッシュ状態が定義されている。
I: 行が無効SC: 行が共有されクリーンUC: 行が排他的/一意的でクリーンSD: 行が共有されダーティUD: 行が排他的/一意的でダーティUD_T: タイムアウトを伴うUD。ストア条件が失敗し、キャッシュラインがIからUDに遷移した場合、失敗の回数がある閾値(コンフィギュレーションで定義)以上であれば、代わりにUD_Tに遷移する。UD_Tでは、与えられたサイクル数(これも設定により定義される)の間、リクエスタからラインを追い出すことはできない。これは特定のシナリオでライブロックを避けるために必要である。
以下のグラフは、L1キャッシュに構成された場合のコントローラのステート変異を示している。

ステートの変化は、CPUからの受信リクエスト(または置換など内部で生成されたもの)と、その結果下流に送られた送信リクエストでアノテートされている。 図を簡単にするために、ステートを変えないリクエスト(キャッシュヒットなど)と無効化スヌープ(最終ステートは常にI)は省略している。 また、簡単のため、MOESIプロトコルの典型的な状態遷移のみを示す。 CHIでは、最終状態は最終的にレスポンダから返されるデータのタイプによって決定される(例えば、リクエスタはReadSharedに対する応答としてUDまたはUCデータを受け取るかもしれない)。
以下の図は、中間レベルのキャッシュコントローラ(プライベートL2、共有L3、HNFなど)の遷移を示している:


前の場合と同様に、簡単のためキャッシュ・ヒットは省略している。
RU: 上流のリクエスタがUCまたはUDのラインを持っているRSC: 1つ以上の上流リクエスタがSCのラインを持っているRSD: 1つの上流リクエスタがSDのラインを持っており、他の人はSCのラインを持っているかもしれないRUSC:RSC+ 現在のドメインはまだ排他的アクセスを持っているRUSD:RSD+ 現在のドメインはまだ排他的アクセスを持っている
キャッシュラインがローカル・キャッシュと上流キャッシュの両方に存在する場合、以下の組み合わせの状態が可能である:
UD_RSC,SD_RSC,UC_RSC,SC_RSCUD_RU,UC_RUUD_RSD,SD_RSD
"UD"は"Unique Dirty"を意味する。つまり、もとの状態は一つのキャッシュが書き込み可能かつ最新データを保持している状態である。 "RSC"は1つ以上の上流リクエスタがSCのラインを持っている状態である。別キャッシュまたはエージェントが"Shared Read"を要求したため、それに応じて現在Unique Dirty (UD)なコピーを保持しているキャッシュが、そのラインを他者と共有するべく、クリーンなデータを返し、最終的に"SC(Shared Clean)" 状態へ移行しようとしている段階を表している。
RUSCとRUSDステート (上の図では省略) は、コントローラがローカルキャッシュに持たずに排他アクセス許可を持つ行を追跡するために使用される。
これは、ローカルブロックが上流のコピーをバックインバリデートすることなく割り当て解除できるnon-inclusiveキャッシュで可能である。
キャッシュ・コントローラーが HNF (ホーム・ノード) の場合、ステートの変異は、以下の違いを除いて、基本的に中間レベル キャッシュと同じである:
- 下流のコンポーネントは SN (スレーブ・ノード) だけであるため、下流からデータを取得するために
ReadNoSnpが送信される。 - キャッシュおよびディレクトリのミスでは、有効な場合、DMT (ダイレクト メモリ転送) が使用される。
- キャッシュのミスおよびディレクトリのヒットでは、有効な場合、DCT (ダイレクト キャッシュ転送) が使用される。
DCTおよびDMTトランザクションの詳細については、CHI仕様のセクション1.7および2.3.1を参照すること。 DMTおよびDCTは、リクエストのデータソースが元のリクエスタに直接データを送信できるようにするCHI機能である。 DMTリクエストでは、SNはデータを直接RNに送信する(HNに最初に送信し、HNがそれをRNに転送する)。 DCTが有効な場合、HNはSnoopeeにHNと元の要求者の両方にデータを送信するよう要求することもできるため、HNはデータをキャッシュすることもできる。 これはコンフィギュレーションパラメータで定義されたアロケーションポリシーに依存する。 割り当てポリシーはキャッシュの状態遷移も変更することに注意すること。 簡単にするために、上の図はinclusiveキャッシュを示している。