CPUとプログラム
Code 2015 in 定山渓 発表資料
niiyama.sh
CPUとプログラム
• 本日は以下の4つのテーマについてお話しします
• キャッシュ
• パイプライン
• スーパースカラー
• マルチコアとハイパースレッディング
• 過去に発表済みの資料、今後の発表予定資料からの抜粋になります
• http://www.slideshare.net/dorniiyama
1. キャッシュ
1.1 ハードウェア構成
• 左図の構成で説明を進めます
• CPUによって実装が異なるので、機
種固有の説明は省きます。
• 私なりに考えた「キャッシュの基礎
を理解する」ための仮想CPUです。
• 「そこそこ」ワーストケースで考えま
す。
• L1、L2キャッシュはミスヒット。
• 細かい用語は後ほど。
Chip
Processor
CPU Core
L2 Cache
Mem Ctrl
DRAM
PCIe
HW…
MMU
L1 Cache
1.2 メモリからデータを
読み出してみよう
• 例えば、以下のC言語プ
ログラム上は左の赤枠の
ような命令に置き換えら
れます。
• ※ARM命令の場合
int hoge = *__bss_start__;
1.3 その前に…レジスタって?
• パソコン初心者向け説明
• CPUはメモリに情報を
置く
• メモリに入りきらない
ときはHDDに退避
CPU
DRAM HDD
実はCPUはメモリに直接アクセスできません
1.4 レジスタ=CPU内部メモリ
• CPUはレジスタのデータに対して
のみ演算可能。
• メモリの値を直接制御できない。
• データ読み出しはメモリから
レジスタに転送し、レジスタ
を読む。
• データ書き込みはレジスタに
書き、レジスタの内容をメモ
リに転送する。
CPU
DRAM HDD
演算回路
レジスタ
レジスタ
キャッシュ
1.5 LEVEL 1 CACHE
• CPUが最初にアクセスす
るメモリ領域
• 一番高速&一番サイズが
小さいメモリ
• CPUクロックと同一ク
ロックで読み書き可能
• 数k∼数100kBytes程度
MMU
物理アドレス
Level 1 Cache
データ物理アドレス
データ物理アドレス
データ物理アドレス
データ物理アドレス
Miss Hit Hit
1.5.1 DETAILS OF CACHE
Level 1 Cache
アドレス
00000000000000000 000000000 000000
データ(1 word)
00000000 00000000 00000000 00000000
Cache Entry Table
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
=?
データ1
1 word (4bytes)
データ2
データ3
データn①
②
③
0
1
511
1.5.2 N-WAY ASSOCIATIVE
CACHE
• nウェイアソシアティブ
• キャッシュが複数(n)毎
• 同一インデックスに対
して複数エントリを持
つことでヒット率向上。
Cache Entry Table
Cache Entry Table
Cache Entry Table
Cache Entry Table
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
タグ(上位アドレス) データ
アドレス
000000000000000000 000000000 00000
=?
Hit or M
1.5.3 MISS HIT!
• キャッシュ内のデータをライトバッ
ク
• データを読み込むためのキャッ
シュエントリを確保するため。
• LRU/ランダム/ラウンドロビン
• L2キャッシュから読み出し
• 読み出し終わるまでCPUはス
トール(パイプライン完全停止)
L2 Cache
Level 1 Cache
データ物理アドレス
データ物理アドレス
データ物理アドレス
データ物理アドレス
1.6 LEVEL 2
CACHE
About Level 2 Cache
Processor
CPU Core
L2 Cache
Mem Ctrl
DRAM
PCIe
HW…
MMU
L1 Cache
1.6.1 LEVEL2 CACHE
SEQUENCE
Address
確定
Tag
出力
比較
Data
出力
確定
Bus Clock
L1 Cacheがアドレスを出力
L2 cacheがアドレスを確定
Tag読み出し制御
Tagが出力される
Tag比較 -> Hit !
Data読み出し制御
Dataが出力される
L1 Cacheへデータを返す
読み出しに8 Clock必要
1.7 DYNAMIC
RANDOM
ACCESS
MEMORY
About DRAM
Processor
CPU Core
L2 Cache
Mem Ctrl
DRAM
PCIe
HW…
MMU
L1 Cache
1.7.1 外部デバイスアクセス
• DRAMは外部デバイス
• 制御用のHWが必要
• 非常に低速
• CPUクロックの5∼10
分の1
1.7.2 DDR3-SDRAM READTIMING
参考資料:
http://www.samsung.com/global/business/semiconductor/file/product/
ddr3_device_operation_timing_diagram_rev121.pdf
10 Clock@8wordバーストリード(キャッシュ1ラインフィルに相当)
1.7.3 DDR3-SDRAM
STATE CHART
• DDR3-SDRAMの内部状態遷移図
• HW IPとして提供されること
が多いのでこれを理解してい
る人は少ないと思います。
• 重要キーワード
• ModeRegister
• プリチャージ
• リフレッシュ
1.7.4 DRAMとキャッシュ
• DRAMはキャッシュに接続さ
れる前提で機能実装
• ラインフィルに必要なバー
ストモード
• 全てシングルアクセスす
ると致命的に遅い
• 要求されたデータから順
にリード可能
Single Word Read = 7 Clock/Word
8 Words Burst Read = 1.25 Clock/Word
(10 Clock / 8 Words)
DRAMとキャッシュは密接な関係にあります
1.8 ヒット率と
アクセス時間
に関する考察
Consideration
Processor
CPU Core
L2 Cache
Mem Ctrl
DRAM
PCIe
HW…
MMU
L1 Cache
?
1.8.1 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
1.8.2 キャッシュヒット率を
考慮
• キャッシュヒット率(仮定)
• L1、L2ともにhit率 = 90.0%と仮定。
• Avarage AccessTime = tL1×0.9 + tL2 × (1 - 0.9) + tDDR3 × (1 - 0.9) × 0.9
= 4.22[clock]
• バスクロックが遅いと?
• 同一クロックであっても外部バス速度が遅いCPUがあります。
• 例:Core2Duo 667MHz、Celeron 533MHz
• Avarage AccessTime = tL1×0.9 + (tL2 × (1 - 0.9) + tDDR3 × (1 - 0.9) ×
0.9) × 667/533 = 5.05[clock]
• ざっくり計算です。
キャッシュやメモリ制御回路が
大部分を占めます。
1.9 実験
Study
Processor
CPU Core
L2 Cache
Mem Ctrl
DRAM
PCIe
HW…
MMU
L1 Cache
?
• Intel Performance Counter Monitorで実験してみましょう。
• 通常のループ
• 残念なループ
• ブロッキング
• アンローリング
• 行列計算
• フォールスシェアリング
1.9.1 通常のループ
• src[row] += dst[row][col]
• dstのサイズ>>キャッシュ
• キャッシュ1ラインの
ワード数ごとにキャッシュ
ミスヒット。
0
1
dst
9
row
0 0
1
src
65535
1 0
9 65534
9 65535
row col
キャッシュ
サイズ
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);
}
}
1.9.2 残念なループ
• rowのインクリメントを先
にする。
• インクリメント>>キャッ
シュ
• 毎回ミスヒットする。
0
1
dst
9
row
0 0
1
src
65535
1 0
9 65534
9 65535
row col
キャッシュ
サイズ
for (unsigned long col = 0; col < COL_SIZE; col++) {
for (unsigned long row = 0; row < ROW_SIZE; row++) {
*(dst + row) += *(src + row * COL_SIZE + col);
}
}
1.9.3 ブロッキング
• キャッシュサイズの範囲内
で一通り処理する。
• 終わったら次の領域に移る。
• ミスヒットが格段に減る。
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);
}
}
0
1
dst
9
row
0 0
1
src
65535
1 0
9 65534
9 65535
row col
キャッシュ
サイズ
ブロック
サイズ
1.9.4 ループアンローリング
• ループ処理を展開して分岐命
令を削減
• 展開しすぎるとプログラム
が大きくなり、命令キャッ
シュミスが増える
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++);
}
}
処理
インクリメント
分岐判定
処理
インクリメント
分岐判定
処理
インクリメント
分岐判定
処理
インクリメント
処理
インクリメント
処理
インクリメント
…
…
実行命令数が減る
=処理時間も減る
プログラムサイズは
増える
1.9.5 行列計算
• 普通にアルゴリズムを書くと、先ほどの「普通のルー
プ」と「残念なループ」の組み合わせになる。
• 片方をわざと行列を入れ替えて定義する
int A[row][col];
int B[col]row];
int A[row][col];
int B[row][col];
1.9.6 フォールスシェアリング
• 複数のスレッドが同一キャッシュラインのデー
タにライトアクセスするときに発生し得る問題。
Core1 Core2
Cache Line Cache Line
DRAM
Core 1とCore2は異なるアドレスにライトする。
アドレスは異なるが、キャッシュラインは同一。
Core1がデータを書き換える。
他コアもキャッシュしているため、DRAMにライトバック。
Core2はDRAMとキャッシュが不一致のため、キャッシュさ
れていたデータは「無効(データ無し)」とする。
Core2がデータを書き換える。
ミスヒットが発生し、DRAMからデータを読み出す。
1.9.7 フォールスシェアリング
解決策
• 複数のスレッドで共有する必要の無いデータはアドレス
が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は無し
1.9.8 実験結果:ループ
• 「残念なループ」はキャッシュヒッ
ト率が低く、DRAMアクセスが多
い。
• 「ブロッキング」はDRAMアクセス
が少ない。
• 簡単なプログラムのため差が出
にくかったかも。
• テストプログラム以外のプロセ
スのカウント値も含まれている
と思われます。
時間[S] L1 HIT
DRAM
READ
普通 1.68 99.82 5542MB
残念 14.09 89.54 41100MB
ブロッキ
ング
1.63 99.95 283MB
アンロー
リング
1.62 99.91 5460MB
1.9.9 実験結果:行列計算/シェ
アリング
• 行列を入れ替えるとキャッシュ
ヒット率が向上しDRAMアクセス
が減る。
• フォールスシェアリングを回避
することによりDRAMアクセスが
半分になっている。
• 「ループ」、「行列計算」、
「シェアリング」はそれぞれ
異なるテストプログラムを実
行しています。
時間[S] L1 HIT
DRAM
READ
通常 13.33 92.30 49.8GB
行列
入れ替
2.06 99.75 10.7GB
時間[S] L1 HIT
DRAM
READ
FALSE
SHARE
10.54 95.42 926MB
NONE
SHARED
4.62 98.77 421MB
2. パイプライン
並列処理の話をする前に…
2.1 入力と出力
• 装置には必ず「入力」、
「出力」があり、「入力」
から「出力」が得られる
までに「時間」が必要と
なります。
• CPUも「命令」を入力と
し、「データ」を出力し
ます。
装置
お金 ジュース
CPU
命令
データ
データ
2.2 処理時間
• 入力してから出力が得られる
までの時間を処理時間と定義
します。
• CPUの場合、メモリから命
令を読み出し、結果を書き
込むまでの時間をクロック
数で表現します。
• これをCPI(Clock Per
Instruction)と呼びます。
メモリ
CPU
t[clocks]
2.3 CPI値の例
CPI
8086 15
80286 6
80486 1.7
Xeon 0.25
CPI値は実行するプログラムにもよって異なるので、あくまでも
参考値です。(参考文献2と5より)
2.4 処理時間(昔のCPU)
CPU
読み出し
デコード
書き込み
レジスタ
メモリ
実行
ちょーざっくり
一つの命令が終わってから
次の命令を読み出す。
一つの命令をCPU内部で複数
の命令(マイクロコード)に分
割して実行する。
2.5 無駄な時間(昔のCPU)
CPU
読み出し
デコード
書き込み
レジスタ
メモリ
実行
ちょーざっくり
動作中の一カ所を除き、
他の回路は何もしていない。
2.6 RISCの登場(ざっくり)
CPU
読み出し
デコード
書き込み
レジスタ
メモリ
実行
動作していないのはもったいな
い。次の命令を読んじゃえ!
メモリは遅いからキャッシュを
付けよう。
マイクロコードはやめて
ハードで実装しよう
2.7 パイプラインの例
• CPUの命令実行部分を機能的に分
割したもの
• IF:命令フェッチ
• RF:命令デコード
• EX:命令実行
• MEM:保存先計算
• WR:保存(メモリ/レジスタ)
IF RF EX ME WR
この順で命令を実行
5クロックで1命令を実行
2.8 命令の同時実行
IF RF EX ME WR
IF RF EX ME WR
IF RF EX ME WR
IF RF EX ME WR
IF RF EX ME WR
IF RF EX ME WR
命令1
命令2
命令6
同時に5命令を実行可能
毎1クロック毎に1命令実行完了
2.9 パイプラインの限界
• パイプラインとキャッシュにより、理論上は
最速で1クロックあたり1命令実行。=1.0[IPC]
• IPC = Instruction Per Clock
• どんなに工夫してもIPCは1.0の壁を超えるこ
とは不可能。
2.10 IPCを1.0以上にする解決策
は?
• 実行回路を複数用意する
• スーパスカラー
• マルチコア
• ハードウェアスレッディ
ング
3. スーパー
スカラー
実行ユニット並列化
3.1 スーパスカラーの概念
• CPUコア内部にパイプラ
インを複数用意
• 命令を同時実行するこ
とで高速化
• ソフトウェアからは並
列実行数不明
IF RF EX ME WR
パイプライン1段
パイプライン2段
IF RF EX ME WR
IF RF EX ME WR
RAM(Cache)
Register
RAM(Cache)
Register
3.2 スーパースカラーの実際1
Inst Decoder
RF EX ME WR
Inst
Cache Inst Decoder
Inst Queue
Inst Inst Inst Inst
RF EX ME WR
Data
CacheRegister
Register
• スーパスカラーの実際のパイプライン
• 複数命令を同時に読み出してデコード
• 複数命令をキューに入れる
• 依存性が無い命令を同時実行
全部が複数あるわけではない
3.3 スーパースカラーの実際2
• EXは対称ではない
• SandyBridgeは演算が3way、メモリ制御が3way
• 同時実行する可能性が高い回路のみ複数実装
引用元:http://pc.watch.impress.co.jp/docs/column/kaigai/20130602_601851.html
4. マルチコア
複数CPUによる同時実行
4.1 マルチコアにする目的
• CPUを複数用意する目的
• 処理の高速化
• スレッドやプロセスを
同時実行
• 消費電力を抑える
• 消費電力を押さえつつ
高速化
汎用PCで一般的な対象マルチプロセッサ(SMP)について説明します
4.2 ソフトウェアから見た問題
• 同期
• 同一のリソース(メモリ領域)に対するアトミック
なアクセス
• キャッシュコヒーレンシ
• それぞれのコアがキャッシュを持つため、一貫性
を保つ仕組みが必要
4.3 同期の問題
• セマフォ等、フラグ状態によ
る排他制御が必須
• シングルプロセッサでは割
り込み禁止で実現できる。
• マルチコアはHW支援必
須。
• 共有フラグにアクセスすると
きにHWがLock制御
flag = 0:アクセス可能
flag = 1:アクセス不可
CPU1 CPU2
Memory
Shared
Data
Flag
4.4 同期問題の解決
• Lock信号を用意
• アトミック命令実行時に
Lock信号をアサート(有
効化)する。
• L1キャッシュにアクセス
するときはアサートしな
い。(コヒーレンシ制御
で解決)
CPU1 CPU2
Memory
Shared
Data
Flag
Lock
4.5 キャッシュコヒーレンシ
の問題
• 同じ領域を複数のコアがキャッ
シュしている
• 一方のコアがデータをライ
トすると不整合が発生する。
• リードは問題無い。
• キャッシュコヒーレンシプロト
コルにより不整合状態を解決
する
CPU1
Memory
Shared
Data
L1 cache
Shared
Data
L1 cache
Shared
Data
CPU2
4.6 コヒーレンシプロトコル
• MESI/MOESIプロトコル
• M:Modified
• 自分だけがキャッシュ+DRAMと不
一致
• O:Owned
• 他CPUと同内容をキャッシュ+DRAM
と不一致
• E:Exclusive
• 自分のみがキャッシュ
• S:Shared
• 他CPUと同内容をキャッシュ+DRAM
と一致
• I:Invalid
• 無効(キャッシュしていない)
MO
E S
I
5. ハードウェア
スレッディング
スーパスカラーの効率化
5.1 スーパスカラーとマルチコア
の問題
• 複数のパイプラインが有効活用されない
• 命令の依存性が高く同時実行が難しい
• 回路規模が大きくなる
• ハードウェアのコスト上昇
• 消費電力上昇
5.2 ハードウェアスレッディング
• ソフトウェアから見たハードウェ
アリソースを複数用意
• ソフトウェアは複数のCPUと
認識して処理を行う
• ハードウェアが複数スレッドの
命令を交互に実行
• OSが行うプロセスス1ケー
ジューリングをハードウェア
が実行するイメージ
CPU
Reg
IRQ
PIPE LINE
CPU
Reg
IRQ
PIPE LINE
Reg
IRQ
5.3 HTのイメージ
• OSは複数CPUとみなしてス
レッドをスケジュール
• 所定のタイミングで実行する
スレッドを切り替える
• レイテンシの長いイベント
• キャッスミスなど
• 一定間隔で交互に
5.4 HTの効果があるパターン
• 各スレッドでリソースの競合が発生しない
• 実行ユニット(以下の図ではALUは効果あり)
• メモリ
6. 同時実行の
まとめ
それぞれの特徴を整理
6.1 まとめ
• 同時実行するための仕組みには複数の実現手段
• 実行ユニット、物理コア、レジスタを複数用意
• 実現手段により特徴が異なる
• それぞれに特徴があり、組み合わせて性能向上
を図る
7. 同時実行の
実験
同時実行の実験
7.1 FALSE SHARING
• 2つのスレッドが異なるメモ
リを使用しているにも関わらず、
キャッシュの構造上、メモリ
の共有状態にあることを言う
• どちらかのスレッド(CPU)がメ
モリを書き換えると、もう一
方のスレッドのキャッシュが
無効化される
• キャッシュコヒーレンシ
Core1 Core2
Cache Line Cache Line
DRAM
異なるアドレスだが、
キャッシュは同一領域管理
7.2 FALSE SHARINGとHT
• 実行する物理コアが異な
る
• False Sharingが発生
• 実行する物理コアが同一
• False Sharingは発生しな
い
Core1 Core2
Cache Line Cache Line
Core1 Core2
Cache Line
7.3 FALSE SHARING実験
• 実験
• 2つのスレッドが異なるアドレスにデータを書き続ける
• 隣り合ったアドレス、64バイトずらしたアドレスへの書き込みの違い
• 異なる物理コア、同一物理コア内の異なる論理コア
アドレスオフセット/コア 同一物理コア 異なる物理コア
1バイト 2.5[s] 3.7[s]
64バイト 2.5[s] 1.6[s]
7.4 PRODUCER CONSUMER
THREADING MODEL
• Producer : データ生成
• Consumer : データ使用
• 例:
• P : ファイル読み出し
• C : 動画デコード
P C
P C
P C
P C
P P
C C
P P
C C
Model 1
Model 2
time
Thread 1
Thread 2
Thread 1
Thread 2
7.5 PRODUCER CONSUMER
実験
• Model1とModel2の比較
• Model1はキャッシュが同一
• Model2はキャッシュが異なるため、コヒーレンシ制御が多発
MODEL/コア 同一論理
同物理
異論理
異物理
MODEL1
3.6[s] 2.4[s] 1.9[s]
99.9[%] 99.9[%] 99.9[%]
MODEL2
3.3[s] 2.4[s] 2.1[s]
99.9[%] 99.9[%] 98.9[%]
7.6 PARALLELISM OF
HARDWARETHREADING
• HyperThreadingは実行ユ
ニットが複数あるときに
効果がある
• 例:
• ALUは複数の同時実
行可能
• それ以外は1命令のみ
ALUは3つあるが、
Divide(除算)は1つ
7.7 HARDWARETHREADINGと
SUPERSCALER実験
• 実験1
• 加算だけを行うスレッドを2つ実行
• 実験2
• 除算だけを行うスレッドを2つ実行
スレッド/コア
同一
論理
同一物理
異論理
異物理
加算 3.4[s] 1.8[s] 1.9[s]
除算 4.2[s] 3.4[s] 2.2[s]
参考文献
• アーキテクチャ全般
• 1. David A.Patterson/John L.Hennessy; パターソン&ヘネシー コンピュータの構成と設計 第4版, 日経BP
社, 2011年.
• 2. 中森 章; マイクロプロセッサ・アーキテクチャ入門, CQ出版, 2004年.
• 3. 安藤壽茂; コンピュータアーキテクチャの話, マイナビニュース
• 実例
• 4. Intel® 64 and IA-32 Architectures Software Developer's ManualVolume 3A: System Programming Guide,
Part 1
• 5. Intel® 64 and IA-32 Architectures Optimization Reference Manual
• 6. Performance Analysis Guide for Intel® Core™ i7 Processor and Intel® Xeon™ 5500 processors

Code jp2015 cpuの話