キャッシュとは
キャッシュの概要
前述したように、Cortex-M7にはハーバードキャッシュ(命令キャッシュとデータキャッシュ)を搭載しています。キャッシュのサイズは、マイコンベンダーのオプションになっていて、命令キャッシュとデータキャッシュで各々4KB~64KBを選ぶことができます。搭載しない(サイズ0KB)も選択できますが、おそらくそのようなベンダーはいないでしょう。
キャッシュはAXIMに付随している構成になっていますので、TCM経由の命令とデータは、扱うことができません。もし、TCMでキャッシュを搭載したい場合は、マイコンベンダーが独自のアーキテクチャで組み込む必要があります。
コアに搭載していますのでL1(1次)キャッシュと呼ばれています。もし、L2(2次)キャッシュを搭載したい場合は、Arm CoreLink L2C-310レベル2キャッシュコントローラの仕様に準拠して、マイコンベンダーが独自に組み込んでAXIインターフェースに接続すれば、AXIMが制御することができます。マイコンベンダーが独自のL2キャッシュを共有メモリ上にインプリメントすることも可能ですが、いずれにしろL1キャッシュとの一貫性はサポートされていません。
命令キャッシュは2-ウェイセットアソシアティブ、データキャッシュは4-ウェイセットアソシアティブ構造です。n-ウェイセットアソシアティブとは、キャッシュ内のラインを選択する方式の一つです。構成の詳細は、各々のキャッシュの章で述べます。どちらのキャッシュも、ECCをベンダーオプションで選択することが可能です。オプションを選択していない製品もありますので、製品のマニュアルを参照してください。
ユーザーがキャッシュを容易にメンテできるように複数のレジスタが準備されています。これらのレジスタを操作することにより、キャッシュの有効化/無効化、クリーン化が簡単にできるようになっています。サポートしている属性は「ライトスルー、書き込み割り当てなし」、「ライトバック、書き込み割り当てなし」、「ライトバック、書き込み割り当てあり」です。各々の説明は、豆知識5をご参照ください。
補足
話がすこしそれますが、冒頭でTCM用のキャッシュの話をしました。実際にCortex-M7を搭載した製品でTCMにキャッシュを搭載しているマイコンがあります。TCMにはITCMとDTCMがあるので、それぞれに命令キャッシュ、データキャッシュを組み込む必要があるように思えますが、アクセスが遅いメモリはFlashメモリで、DTCMに接続されるメモリは読み出し速度の速いSRAMという前提なので、DTCMにはキャッシュは不要です。
では、Flashに搭載されてITCMでアクセスされる領域におかれたデータはアクセスが遅くなるかというと、そんなことはありません。ITCM上に命令キャッシュ、データキャッシュを統合したキャッシュを搭載して、ITCMからデータを取り出すことができます。逆に、DTCMのSRAMに命令を置いても、ウエイトサイクル無しで、問題なく実行できます。
キャッシュのまとめ
- 最適性能を出すためのハーバードアーキテクチャ
- 命令およびデータ共に個別に設定可能なサイズ(各々4KB – 64KB)(これはマイコンベンダーに対するオプション。搭載サイズは、マイコン製品のマニュアルに明記されている。)
- キャッシュはAXIM領域のみ(TCMやAHBPには対応していない)
- 命令キャッシュは2-ウェイセットアソシアティブ、データキャッシュは4-ウェイセットアソシアティブ
- Armv7E-Mシステムアーキテクチャに必要な拡張機能付
- キャッシュメンテナンス操作の追加:キャッシュメンテナンスの為のレジスタ
- システムソフトウェアはキャッシュを装備することにより影響を受ける
- 次の属性をフルサポート
- ライトスルー、書き込み割り当てなし
- ライトバック、書き込み割り当てなし
- ライトバック、書き込み割り当てあり
- ハードウエアの一貫性のサポートなし
- 共有メモリ上にL2キャッシュをインプリメントする場合、L1との一貫性はサポートされない
- ECCはオプション(すべてのキャッシュECCは内部で処理される)
キャッシュって何
もうすでにご存知で、よけいなお世話だと思いますが…「容量が大きいが、低速のメモリ」を主メモリとし、それより数倍以上の高速メモリ(これをキャッシュメモリまたはキャッシュと呼ぶ)を用意して、最近アクセスされた主メモリの命令やデータをキャッシュに残しておき、次に同じ番地がアクセスされたときは、キャッシュをアクセスすることにより、データアクセスを高速に処理する手法です。
L1キャッシュ、L2キャッシュの意味
L1のLはレベル(LeveL)の意味です。1次キャッシュという言い方もあります。プライマリキャッシュ(primary cache)と呼ばれることもあります。一般的に、コアから近い順にL1(1次)、L2(2次)…と呼びます。L1キャッシュに収まらない場合に、L1よりも低速ですが、容量が大きいL2キャッシュを使います。Cortex-M7ではAXIMに付随したL1キャッシュを内蔵しています。
キャッシュの基本構成
キャッシュは高速・小容量のメモリですので、通常のSRAMの構造で作られます。内部をタグ部とデータ部に分けて、キャッシュにヒットしたかミスしたかは、タグ部を使って判断します。タグ部の構成でいくつかの方式に分けられます。
タグが一組の場合をダイレクトマップ方式(Direct Mapped)と呼びます。構造が単純なので、作るのは簡単ですがヒット率が他の方式に比べ高くありません。複数のタグで構成する場合をセットアソシアティブ方式(Set Associative)と呼びます。タグの数が多いほどキャッシュヒット率は上昇しますが、作るのが難しくなっていきます。n個のタグにより構成された場合、nウエイセットアソシアティブ方式と呼びます。
Coretx-M7の命令キャッシュは2-ウェイセットアソシアティブ、データキャッシュは4-ウェイセットアソシアティブ構造です。アドレスが与えられると全てのタグと比較される方式をフルアソシアティブ方式(Fully Associative)と呼びます。ヒット率が最も優れていますが、コストが高くなるので通常は用いられません。
キャッシュヒット
ターゲットの命令やデータがキャッシュに存在する場合。
キャッシュミス
ターゲットの命令やデータがキャッシュに存在しない場合。
ラインフィル
全体のキャッシュライン用のバス上の読み出しリクエスト。フィルとはキャッシュがミスした場合にメインメモリの内容をキャッシュに読み込むこと。このラインは、一旦有効になると、その後、キャッシュに割り当てられます。
エビクション(Eviction)
キャッシュがいっぱいの状態で、キャッシュ内に必要なデータを保存し、不要なデータを追い出すこと。エビクション(eviction)は立ち退きという意味です。
ライトスルー(Write through)
CPUがキャッシュにデータを書き込むと同時にメインメモリにも同じデータを書き込む方式。
ライトバック(Write-back)
CPUがキャッシュにデータを書き込む時に、キャッシュが一杯になるまではキャッシュにしか書き込まないで、キャッシュのブロックが追い出されるときにその追い出されるデータをメインメモリに書き込む方式。
Cortex-A編 第9回でも、上記の用語について詳細に説明していますので、ご参照ください。
キャッシュの特徴
概要
キャッシュの歴史は古く、Armができる前から色々なアーキテクチャが考えられてきました。私の持っているマイコンのアーキテクチャに関する本(昭和57年版)にも色々な方式が説明されています。ポイントは、キャッシュのヒット/ミスの判別方式と、ヒットした場合のデータ検索方法です。ヒットした場合、キャッシュ内のどこにヒットしたデータがあるかを、すばやく検索しなくてはなりません。ヒットしてからデータを探し出すまでの一連のプロセスが1サイクルで実行されなければ、キャッシュの意味がありません。
最近の方式の代表的なものは3つあります。本記事はマイコンのアーキテクチャの説明ではないので、詳しくは説明しませんが、データ検索方法から次のようなものが挙げられます。
ダイレクトマップ方式(Direct Mapped)
アドレスに対し、一つのラインを特定する方式です。特徴は内部構造が簡単に作れるということです。
セットアソシアティブ方式(Set Associative)
ダイレクトマップ方式をいくつか並べたものです。n個並べたものをnウエイセットアソシアティブ方式と呼びます。n個のタグにより、ダイレクトマップ方式よりもヒット率を上げることができます。nの数が大きいほどヒット率は上がりますが、回路規模とのトレードオフになるので、各製品で最適なnが選択されます。
フルアソシアティブ方式(Fully Associative)
アドレスと全てのラインを比較する方式です。ライン数が同じならば、他の方式よりもヒット率が高くなりますが、内部の回路が大きくなる欠点があります。
Cortex-M7のキャッシュ
命令キャッシュは、2-ウェイセットアソシアティブ方式が採用されています。この方式は、回路規模が比較的小さくできて、性能は4-ウェイセットアソシアティブと比較しても、そんなに劣りません。
データキャッシュは、4-ウェイセットアソシアティブ方式です。デュアルポートメモリの使用無しで、ロードのデュアルIssueのサポートを行います。32エントリー4ウェイセットアソシアティブ構造になっており、主要なキャッシュヒットおよび新しい割り当てにおいてアップデートされます。
どちらのキャッシュもECCをサポートしていますが、オプションですのでサポートしているかどうかは、製品のマニュアルをご確認ください。
命令キャッシュ 2-ウェイセットアソシアティブ
概要
Cortex-M7の命令キャッシュは2-ウェイセットアソシアティブの構成ですので下図のような構成になります。この例は16KBキャッシュです。1ラインは32バイトですので、2ウェイx256ラインx32バイト=16KBとなります。2-ウェイなので、タグの比較器が2個あって、アドレスのタグ部をデコードして、決まったタグ部出力を同時に比較して、合致するアドレスがあればヒットしたことになります。
キャッシュRAM
Cortex-M7のマニュアルには「キャッシュ」と「キャッシュRAM」の2つの単語が混在して使われています。「キャッシュ」はキャッシュ全体、「キャッシュRAM」はキャッシュの中のRAM部分のことを指します。キャッシュの内部構造の説明の際には「キャッシュRAM」が使われています。
キャッシュRAMは、タグ部とデータ部で構成されています。タグ部はECCが無い場合、4×22ビットで、ECC付きの場合はECCの7ビット分が増えて、4x(22+7)ビットとなります。データ部はECCが無い場合、4×64ビットで、ECC付きの場合はECCの8ビット分が増えて、4x(64+8)ビットとなります。
タグ部とデータ部をあわせてセットと呼んでいます。上図の場合256セットの、2-ウェイということになります。タグ部に含まれるのは、タグ(tag)とインデックス(Index)とタグ値(tag value)と属性(outer attributes)と有効ビット(Valid bit)です(上図では有効ビットのみ記載)。データ部はその名の通りデータです。
RAM | ECC無 | ECC有 |
---|---|---|
タグ部 | 4×22ビット | 4x(22+7)ビット |
データ部 | 4×64ビット | 4x(64+8)ビット |
エラーのリカバー
Cortex-M7プロセッサは、キャッシュ内のRAMにエラーを検出すると、クリーン→無効化→リトライを行うことによってリカバーすることができます。クリーンと無効化操作が完了後に、リトライアクセスを行います。
命令キャッシュでは、常にラインがクリーン(メインメモリとキャッシュのデータが一致している)なので、ラインを無効化するだけです。リトライアクセスにより正しい値を外部メモリから取りこみます。一方、オプションでECCを付けることができます。これは、単一ビットのエラー訂正のために用いられます。ECCの詳細はECCの章で述べます。
データキャッシュ 4-ウェイセットアソシアティブ
概要
Cortex-M7のデータキャッシュは4-ウェイセットアソシアティブの構成ですので下図のような構成になります。この例は8KBキャッシュです。1ラインは32バイトですので、4ウェイx64ラインx32バイト=16KBとなります。4-ウェイなので、タグの比較器が4個あって、アドレスのタグ部をデコードして決まったタグ部出力を同時に比較して、合致するアドレスがあればヒットしたことになります。
キャッシュRAM
データキャッシュのキャッシュRAMも、タグ部とデータ部で構成されています。タグ部はECCが無い場合、4×26ビットで、ECC付きの場合はECCの7ビット分が増えて、4x(26+7)ビットとなります。データ部はECCが無い場合、8×32ビットで、ECC付きの場合はECCの7ビット分が増えて、8x(32+7)ビットとなります。タグ部に含まれるのは、タグ(tag)とインデックス(Index)とタグ値(tag value)と属性(outer attributes、上図ではCで記述)と有効ビット(Valid bit)とダーティビット(Dirty bit)です(上図ではVとDとCのみ記載)。
RAM | ECC無 | ECC有 |
---|---|---|
タグ部 | 4×26ビット | 4x(26+7)ビット |
データ部 | 8×32ビット | 8x(32+7)ビット |
ダーティビット(Dirty bit)
メモリがライトバック(WB)の場合、キャッシュに書き込んだデータを毎回メインメモリへ反映しないで、キャッシュのみを更新します。その為、そのラインがエビクション時にメインメモリにライトバックして、一致を取ります。すると、ある期間、メインメモリとキャッシュのデータが一致しません。そこで、キャッシュラインをダーティとしてマークして、タグメモリ上にダーティビットを設けて、メインメモリのデータと一致しているかどうかを管理します。
エラーのリカバー
データキャッシュでは、キャッシュラインはダーティになる可能性があります。RAMの訂正操作は、キャッシュのためのクリーン化と無効化操作の一部として行われます。これはライトバッファにおいて起こり、訂正されたデータは、外部メモリにライトバックされます。アクセスはリトライされ、正しい値が外部メモリから読まれます。もし、その時データが訂正できないならば、エラーは修復不能であるといえます。
キャッシュとメモリ属性
属性
メモリ属性はデフォルトでメモリ領域ごとに設定されていますが、MPU(MPU_RASR:MPU Region Attribute and Size Register)によりユーザーが定義することができます。これらの属性は、AXIM/キャッシュメモリ・システムの動作に影響をあたえます。
メモリタイプ
メモリのタイプは第6回の豆知識4で説明した3種類があります。
Strongly Ordered
プログラムに書いた順を守ってLoad、Storeを実行するメモリタイプ。(例えば、外部プライベート周辺バスROMテーブル領域)
Device
Load、Storeを実行することにより副作用があるタイプ。投機的実行や同じ動作を繰り返してはいけない。(例えば、外部周辺領域等)
Normal
通常のメモリタイプ。複数回読んでも値は同じ、複数回同じ値を書いても結果は同じ。(例えば、MCUの内蔵RAM等)
Shared(共有)/ Non-shared(共有されない)と排他的アクセス
Shared(共有)は、別のマスタと共有されるメモリにだけ適用されます。(一貫性が保証されます)。デフォルトでは、データ・アクセスがD-キャッシュにキャッシュされないようになっています。言い換えると、デフォルトでは、NormalとNon-shareableメモリ領域だけは、RAMでキャッシュすることができます。適切なキャッシュが有効な場合で、かつメモリタイプがキャッシュ可能な場合にキャッシングが起きます。CACR_ SIWTが1ならば、Shared cacheableメモリ領域もキャッシュすることができます。
メモリタイプ | キャッシュ | マージ | 再スタート | 排他的処理 | |
---|---|---|---|---|---|
Normal | Shared | 不可(*) | 可能 | 可能 | 内部&外部 |
Non-shared | 可能 | 可能 | 可能 | 内部のみ | |
Device | Shared | 不可 | 不可 | 不可 | 内部&外部 |
Non-shared | 不可 | 不可 | 不可 | 内部のみ | |
Strongly Ordered | Shared | 不可 | 不可 | 不可 | 内部&外部 |
(*)CACR.SIWTが1に設定されていない限り。
Shared(共有)としてマークされているメモリ領域への排他的ストア命令のアクセスでなければ、ストアバッファはNormalメモリにいくつかのストアをマージすることができます。
キャッシュされていないShared 排他的トランザクションだけは、排他的外部インターフェースとしてマークされます。CACR.SIWTが1ならば、Sharedのキャッシュ可能なメモリ領域に対するロード/ストア排他的命令は、外部インターフェース上の排他的アクセスという結果にはなりません。
一方、Normalメモリだけは再スタート可能だと考えられます。つまり、複合ワード転送の場合に、割り込みが発生すると終わりまで行なわれずに途中で中断されて、割り込みの処理後に再開されるようになります。このとき、Non-sharedメモリへの排他的なアクセスのための内蔵排他的モニターだけ更新され、チェックされます。内蔵モニターの利用に加えて、必要に応じて、外部メモリ・インターフェースAXIMまたはAHBPを使っている外部モニターを使ってもSharedメモリへの排他的アクセスをチェックすることができます。
こちらも是非
“もっと見る” Cortex-M7編
電力管理、コアデバッグ、浮動小数点ユニット
Cortex-M7もCortex-M3/M4と同じように低消費電力モードをサポートしています。基本はCortex-M3/M4と同じです。Cortex-M7にはWIC(ウェイクアップ割り込みコントローラ)を含むと3種類のスリープを持っていることになります。
AXI転送
AXI転送を行う際には、次に示す制限があります。バーストは、最大32バイト。バースト長さは、最大4転送。Strongly-orderedメモリまたはDeviceメモリの書き込みバーストの最大長は2転送です。Strongly-orderedメモリまたはDeviceメモリの読み出しは、常に1転送です。
キャッシュの初期化と有効化
Cortex-Aで採用されているユニフィケーションのポイント(Point of unification:PoU)と一貫性のポイント(Point of coherency :PoC)の考え方がCortex-M7でも採用されています。