Mais conteúdo relacionado
Semelhante a Cpu cache arch (20)
Cpu cache arch
- 3. ハードウェア構成
左図の構成で説明を進めます
CPUによって実装が異なるので、機種
固有の説明は省きます。
私なりに考えた「キャッシュの基礎を
理解する」ための仮想CPUです。
「そこそこ」ワーストケースで考えます。
TLBヒット、L1、L2キャッシュはミス
ヒット。
細かい用語は後ほど。
Processor Chip
CPU Core
L2 Cache
Mem Ctrl
DRAM
HW…
PCIe
MMU
L1 Cache
- 5. “Le plus important est invisible”
“大切な物は目に見えないんだよ”
–The Little Prince
メモリからデータを読み出し、CPUレジスタにロードされるまで
長い旅路の物語
- 8. About MMU Processor Chip
MEMORY
MANAGEMENT
UNIT
CPU Core
L2 Cache
Mem Ctrl
DRAM
HW…
PCIe
MMU
L1 Cache
- 9. MMU
CPUがデータをロードすると
き、MMUに対してアドレスを
出力します。
MMUでは仮想メモリと物理メ
モリ変換を行います。
TLBというアドレス変換情報
キャッシュがあります。
CPU Core
仮想アドレス
MMU
仮想アドレス物理アドレス
仮想アドレス物理アドレス
仮想アドレス物理アドレス
仮想アドレス物理アドレス
物理アドレス
- 10. 物理アドレスと仮想アドレス
物理アドレス
連続的な実際のアドレス。
仮想アドレス
OSが実行時に動的に割り当てるアドレス
ページ単位の割り当て
4kB、16kB、64kBなど。
不連続なページを連続的に見せる。
プロセス毎に独立したアドレス
あるプロセスからほかのプロセスのアドレ
スにはアクセス不可。(メモリ保護)
物理アドレス仮想アドレス
- 11. 仮想~物理アドレス変換
MMU
仮想アドレス(32bit)
00000000000 00000000000 000000000000
Page Table
物理アドレス
物理アドレス(32bit)
00000000000000000000 000000000000
Page Table
Page Table
Page Table
Page Table
物理アドレス
物理アドレス
物理アドレス
Page Table Entry(PTE)を使ってアドレ
ス変換
TLBはPTEのキャッシュ
TLBミスヒット時はPTEを検索
エントリ数は32~128個程度
PTEミスヒット時はページイン(Disk
-> RAM)
- 12. About Level 1 Cache Processor
LEVEL 1 CACHE
CPU Core
L2 Cache
Mem Ctrl
DRAM
HW…
PCIe
MMU
L1 Cache
- 13. LEVEL 1 CACHE
CPUが最初にアクセスするメ
モリ領域
一番高速&一番サイズが小さ
いメモリ
CPUクロックと同一クロッ
クで読み書き可能
数k~数100kBytes程度
MMU
物理アドレス
Level 1 Cache
物理アドレスデータ
物理アドレスデータ
物理アドレスデータ
物理アドレスデータ
Miss Hit Hit
- 14. DETAILS OF CACHE
アドレス
00000000000000000 000000000 000000
Level 1 Cache
1 word (4bytes)
データ(1 word)
Cache Entry Table
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
00000000 00000000 00000000 00000000
=?
データ1
データ2
データ3
データn ①
②
③
01
511
- 15. CACHE ALGORITHM
~キャッシュの動作をC/C++で表現してみました~
typedef struct {
unsigned long tag;
int data[8];
} CLine;
!
typedef struct {
CLine entry[512 / (8 * sizeof(int)]; // 16 line
} ETable;
ETable cache;
!
bool GetData(int* adrs, int *data) {
unsigned long i = (adrs & 0x000001E0) >> 5;
!
if (cache.entry[i].tag == adrs & 0xFFFFFE00) {
*data = cache.entry[i].data[adrs & 0x0000001F];
}
キャッシュ
:512バイト
ラインあたりのワード数
:8ワード
ライン数
:16ライン
- 16. CACHE ALGORITHM
typedef struct {
unsigned long tag;
int data[8];
} CLine;
!
typedef struct {
CLine entry[512 / (8 * sizeof(int)];
} ETable;
ETable cache;
!
bool GetData(int* adrs, int *data) {
unsigned long i = (adrs & 0x000001E0) >> 5;
!
if (cache.entry[i].tag == adrs & 0xFFFFFE00) {
*data = cache.entry[i].data[adrs & 0x0000001F];
}
・タグ
:0xFFFFFE00
・インデックス
:0x000001E0
・ライン内オフセット
:0x0000001F
アドレスからインデックスを抽出
- 17. CACHE ALGORITHM
typedef struct {
unsigned long tag;
int data[8];
} CLine;
!
typedef struct {
CLine entry[512 / (8 * sizeof(int)];
} ETable;
ETable cache;
!
bool GetData(int* adrs, int *data) {
unsigned long i = (adrs & 0x000001E0) >> 5;
!
if (cache.entry[i].tag == adrs & 0xFFFFFE00) {
*data = cache.entry[i].data[adrs & 0x0000001F];
}
・タグ
:0xFFFFFE00
・インデックス
:0x000001E0
・ライン内オフセット
:0x0000001F
アドレスからタグを抽出して比較
- 18. CACHE ALGORITHM
typedef struct {
unsigned long tag;
int data[8];
} CLine;
!
typedef struct {
CLine entry[512 / (8 * sizeof(int)];
} ETable;
ETable cache;
!
bool GetData(int* adrs, int *data) {
unsigned long i = (adrs & 0x000001E0) >> 5;
!
if (cache.entry[i].tag == adrs & 0xFFFFFE00) {
*data = cache.entry[i].data[adrs & 0x0000001F];
}
・タグ
:0xFFFFFE00
・インデックス
:0x000001E0
・ライン内オフセット
:0x0000001F
アドレスからライン内オフセットを抽出
↑ここはちょっと変だけど許してね
- 19. N-WAY ASSOCIATEVE CACHE
Cache Entry Table
Cache Entry Table
Cache Entry Table
Cache Entry Table
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
nウェイアソシアティブ
キャッシュを複数(n)毎持つ
ダイレクトマップの欠点を解決
同一インデックスに対して
複数エントリを持つことで
ヒット率向上。
アドレス
000000000000000000 000000000 00000
=?
Hit or Miss ?
- 20. MISS HIT!
キャッシュ内のデータをライトバック
データを読み込むためのキャッシュ
エントリを確保するため。
LRU/ランダム/ラウンドロビン
L2キャッシュから読み出し
読み出し終わるまでCPUはストール
(パイプライン完全停止)
Level 1 Cache
物理アドレスデータ
物理アドレスデータ
物理アドレスデータ
物理アドレスデータ
L2 Cache
- 21. About Level 2 Cache Processor
LEVEL 2 CACHE
CPU Core
L2 Cache
Mem Ctrl
DRAM
HW…
PCIe
MMU
L1 Cache
- 22. LEVEL2 CACHE SEQUENCE
Address
確定
Tag
出力
比較
Data
出力
確定
Bus Clock
L1 Cacheがアドレスを出力
L2 cacheがアドレスを確定
Tag読み出し制御
Tagが出力される
Tag比較 -> Hit !
Data読み出し制御
Dataが出力される
L1 Cacheへデータを返す
読み出しに8 Clock必要
- 23. About DRAM Processor
DYNAMIC
RANDOM
ACCESS
MEMORY
CPU Core
L2 Cache
Mem Ctrl
DRAM
HW…
PCIe
MMU
L1 Cache
- 26. DDR3-SDRAM STATE CHART
DDR3-SDRAMの内部状態遷移図
HW IPとして提供されることが多
いのでこれを理解している人は少
ないと思います。
重要キーワード
ModeRegister
プリチャージ
リフレッシュ
- 27. DRAMとキャッシュ
DRAMはキャッシュに接続され
る前提で機能実装
ラインフィルに必要なバース
トモード
全てシングルアクセスする
と致命的に遅い
要求されたデータから順にリー
ド可能
Single Word Read = 7 Clock/Word
8 Words Burst Read = 1.25 Clock/Word
(10 Clock / 8 Words)
DRAMとキャッシュは密接な関係にあります
- 29. CPUの待ち時間
今までのワーストケースで1wordを読み出す時間を計算
tL1 = 1 Clock
tL2 = 16 Clock (8 × 2CPUの半分のクロックで動作と過程)
tDDR3 = 28 Clock (7 × 4 CPUバスの半分のクロックで動作と過程)
tAllMiss = tL1 + tL2 + tDDR3 = 45 [Clock]
CPUやシステムによって上記の値は全然違います。
実際の値を適用すると、もっとすごいことになります。
http://www.7-cpu.com/cpu/Cortex-A9.html
- 30. キャッシュヒット率を考慮
キャッシュヒット率(仮定)
L1、L2ともにhit率 = 90.0%と仮定。
Avarage Access Time = tL1×0.9 + tL2 × (1 - 0.9) + tDDR3 × (1 -
0.9) × 0.9 = 4.22[clock]
バスクロックが遅いと?
同一クロックであっても外部バス速度が遅いCPUがあります。
例:Core2Duo 667MHz、Celeron 533MHz
Avarage Access Time = tL1×0.9 + (tL2 × (1 - 0.9) + tDDR3 × (1 -
0.9) × 0.9) × 667/533 = 5.05[clock]
ざっくり計算です。
- 34. 通常のループ
src[row] += dst[row][col]
dstのサイズ>>キャッシュ
キャッシュ1ラインのワード数
ごとにキャッシュミスヒット。
row
0
1
src
9
row col
0 0
1
dst
65535
1 0
9 65534
9 65535
キャッシュ
サイズ
for (unsigned long row = 0; row < ROW_SIZE; row++) {
for (unsigned long col = 0; col < COL_SIZE; col++) {
*(dst + row) += *(src + row * COL_SIZE + col);
}
}
- 35. 残念なループ
rowのインクリメントを先にする。
インクリメント>>キャッシュ
毎回ミスヒットする。
row
0
1
src
9
row col
0 0
1
dst
65535
1 0
9 65534
9 65535
キャッシュ
サイズ
for (int col = 0; col < COL_SIZE; col++) {
for (int row = 0; row < ROW_SIZE; row++) {
*(dst + row) += *(src + row * COL_SIZE + col);
}
}
- 36. ブロッキング
キャッシュサイズの範囲内で
一通り処理する。
終わったら次の領域に移る。
ミスヒットが格段に減る。
row
0
1
src
9
row col
0 0
1
dst
65535
1 0
9 65534
9 65535
キャッシュ
サイズ
for (int Blk = 0; Blk < COL_SIZE; Blk += BLKSIZE) {
for (int row = 0; row < ROW_SIZE; row++) {
for (int col = Blk; col < Blk + BLKSIZE; col++) {
*(dst + row) += *(src + Blk * BLKSIZE + col);
}
}
}
ブロック
サイズ
- 37. ループアンローリング
ループ処理を展開して分岐命
令を削減
展開しすぎるとプログラム
が大きくなり、命令キャッ
シュミスが増える
for (unsigned long row = 0; row < ROW_SIZE; row++) {
for (unsigned long col = 0; col < COL_SIZE;) {
*(data_dst + row) += *(data_src + row * COL_SIZE + col++);
*(data_dst + row) += *(data_src + row * COL_SIZE + col++);
*(data_dst + row) += *(data_src + row * COL_SIZE + col++);
…略…
*(data_dst + row) += *(data_src + row * COL_SIZE + col++);
}
}
処理
インクリメント
分岐判定
処理
インクリメント
分岐判定
処理
インクリメント
分岐判定
処理
インクリメント
処理
インクリメント
処理
インクリメント
…
…
実行命令数が減る
=処理時間も減る
プログラムサイズは
増える
- 39. フォールスシェアリング
複数のスレッドが同一キャッシュラインのデータにライト
アクセスするときに発生し得る問題。
Core1 Core2
Cache Line Cache Line
DRAM
Core 1とCore2は異なるアドレスにライトする。
アドレスは異なるが、キャッシュラインは同一。
Core1がデータを書き換える。
他コアもキャッシュしているため、DRAMにライトバック。
Core2はDRAMとキャッシュが不一致のため、キャッシュさ
れていたデータは「無効(データ無し)」とする。
Core2がデータを書き換える。
ミスヒットが発生し、DRAMからデータを読み出す。
- 40. フォールスシェアリング解決策
複数のスレッドで共有する必要の無いデータはアドレスが
64バイト以上離れるようにする。
Core1 Core2
Cache Line Cache Line
DRAM
void worker_thread1(void) {
for (int i = 0; i < MAX; i++)
dstArea[0] += srcArea[i];
}
!
void worker_thread2(void) {
for (int i = 0; i < MAX; i++)
dstArea[1] += srcArea[i];
}
!
void worker_thread3(void) {
for (int i = 0; i < MAX; i++)
dstArea[64] += srcArea[i];
}
thread1と2はフォールスシェアリング
thread1と3は無し
- 41. 実験結果:ループ
「残念なループ」はキャッシュヒッ
ト率が低く、DRAMアクセスが多
い。
「ブロッキング」はDRAMアクセ
スが少ない。
簡単なプログラムのため差が
出にくかったかも。
テストプログラム以外のプロセ
スのカウント値も含まれてい
ると思われます。
時間L1 HIT DRAM
READ
普通1.68 99.82 5542MB
残念14.09 89.54 41100MB
ブロッキ
ング1.63 99.95 283MB
アンロー
リング1.62 99.91 5460MB
- 42. 実験結果:行列計算/シェアリング
行列を入れ替えるとキャッシュ
ヒット率が向上しDRAMアクセ
スが減る。
フォールスシェアリングを回避
することによりDRAMアクセス
が半分になっている。
「ループ」、「行列計算」、
「シェアリング」はそれぞ
れ異なるテストプログラムを
実行しています。
時間L1 HIT DRAM
READ
通常13.33 92.30 49.8GB
行列
入れ替え2.06 99.75 10.7GB
時間L1 HIT DRAM
READ
FALSE
SHARE 10.54 95.42 926MB
NONE
SHARED 4.62 98.77 421MB
- 43. 参考資料
アーキテクチャ全般
David A.Patterson/John L.Hennessy; パターソン&ヘネシー コンピュータの構成と設計 第4版,
日経BP社, 2011年.
中森 章; マイクロプロセッサ・アーキテクチャ入門, CQ出版, 2004年.
CPU実例
ARM
Cortex-A9 テクニカルリファレンスマニュアル, r2p2
CoreLink Level 2 Cache Controller L2C-310 Technical Reference Manual, r3p3
Intel
Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System
Programming Guide, Part 1
Intel® 64 and IA-32 Architectures Optimization Reference Manual
Performance Analysis Guide for Intel® Core™ i7 Processor and Intel® Xeon™ 5500
processors