1 - 東京大学

スパコンプログラミング(1)、(Ⅰ)
1
高性能プログラミング技法
の基礎(1)
東京大学情報基盤センター 准教授 塙 敏博
2016年10月18日(火)10:25-12:10
スパコンプログラミング(1)、(Ⅰ)
講義日程(工学部共通科目)
7.
9月27日(今日): ガイダンス
10月4日
1.
2.
l
l ログイン作業、テストプログラム実行
10月18日
4.
l
高性能プログラミング技法の基礎1
(階層メモリ、ループアンローリン
グ)
11月1日(8:30-10:15)
5.
l
l
10.
高性能プログラミング技法の基礎2
(キャッシュブロック化)
l
行列-ベクトル積の並列化
LU分解法(1)
コンテスト課題発表
12月20日
l
LU分解法(2)
1月10日(★大演習室2)
l
13.
行列-行列積の並列化(2)
12月13日
l
11.
行列-行列積の並列化(1)
12月6日
l
12.
11月1日(10:25-12:10)
6.
9.
べき乗法の並列化
11月29日
l
並列数値処理の基本演算(座学)
10月11日:スパコン利用開始
3.
11月22日
l
8.
2
レポートおよびコンテスト課題
(締切:
2017年2月13日(月)24時 厳守
LU分解法(3)
1月13日(金曜、補講日)
l
新しいスパコンの紹介・お試し、
他
10/11はネットワーク障害のため演習ができなかったので
10/18の内容をほとんどやってしまった
スパコンプログラミング(1)、(Ⅰ)
講義の流れ
1. 階層キャッシュメモリ
2. 演算パイプライン
3. ループアンローリング
4. 配列連続アクセス
5. 演習課題
6. レポート課題
3
スパコンプログラミング(1)、(Ⅰ)
階層キャッシュメモリ
超高速メモリは小容量
4
5
スパコンプログラミング(1)、(Ⅰ)
最近の計算機のメモリ階層構造
高速
O(1ナノ秒)
O(10ナノ秒)
O(100
ナノ秒)
O(10
ミリ秒)
レジスタ
バイト
Kバイト
キャッシュ ~Mバイト
メインメモリ
ハードディスク
Gバイト
Gバイト
~Tバイト
大容量
•メインメモリ→レジスタへの転送コストは、
レジスタ上のデータアクセスコストの O(100)倍!
スパコンプログラミング(1)、(Ⅰ)
6
より直観的には…
レジスタ
キャッシュ
メインメモリ
l高性能(=速い)プログラミングをするには、
きわめて小容量のデータ範囲について
何度もアクセス(=局所アクセス)するように
ループを書くしかない
7
スパコンプログラミング(1)、(Ⅰ)
キャッシュの構成例
CPU
セット
メインメモリ
演算器
演算
要求
バンク
(ブロック)
演算
結果
レジスタ
データ供給
データ蓄積
キャッシュメモリの構成
キャッシュメモリ
0
データ供給
1
0
2
9
0
1
6
1
4
データ蓄積
メインメモリ
8
キャッシュ
ディレクトリ
0
1
0
2
1
0
2
1
1
3
1
2
4
1
3
6
1
4
7
6
1
4
キャッシュメモリ
上位
物理アドレス
下位
ブロック内
スパコンプログラミング(1)、(Ⅰ)
8
Reedbush-Uのメモリ構成
●データ
高速
レジスタ
レベル1キャッシュ
(32Kバイト/1コア)
レベル2キャッシュ
(256Kバイト/1コア)
●データ
●データ
レベル3キャッシュ
(45Mバイト/18コア
=1ソケット)
メインメモリ
(256Gバイト/ノード)
●データ
大容量
9
スパコンプログラミング(1)、(Ⅰ)
Reedbush-Uのメモリ構成
●データ
高速
レジスタ
レベル1キャッシュ
(32Kバイト/1コア)
●データ
レベル2キャッシュ
(256Kバイト/1コア)
データが
L1キャッシュ上
にあれば、
速くアクセス可能
レベル3キャッシュ
(45Mバイト/18コア
=1ソケット)
メインメモリ
(256Gバイト/ノード)
大容量
10
スパコンプログラミング(1)、(Ⅰ)
Reedbush-Uのノードのメモリ構成
コア0 コア1 コア2 コア3
コア
32
コア
33
コア
34
コア
35
L1
L1
L1
L1 … L1
L1
L1
L1
L2
L2
L2
L2
L2
L2
L2
L3 (物理的に分散)
L2
L3 (物理的に分散)
メインメモリ
※階層メモリ構成となっている
11
スパコンプログラミング(1)、(Ⅰ)
Reedbush-U全体メモリ構成
コ コ コ コ
ア ア ア ア
0
L 1
L 2
L 3
L
コ
ア
3
L
…2
コ
ア
3
L
3
コ
ア
3
L
4
コ
ア
3
L
5
1 1 1 1
1 1 1 1
L L L L
L L L L
2 2 2 2
2 2 2 2
L3 (物理的
L3 (物理的
に分散)
に分散)
メインメモリ
コ コ コ コ
ア ア ア ア
0
L 1
L 2
L 3
L
コ
ア
3
L
…2
コ
ア
3
L
3
コ
ア
3
L
4
コ
ア
3
L
5
1 1 1 1
1 1 1 1
L L L L
L L L L
2 2 2 2
2 2 2 2
L3 (物理的
L3 (物理的
に分散)
に分散)
メインメモリ
…
コ コ コ コ
ア ア ア ア
0
L 1
L 2
L 3
L
コ
ア
3
L
…2
コ
ア
3
L
3
コ
ア
3
L
4
コ
ア
3
L
5
1 1 1 1
1 1 1 1
L L L L
L L L L
2 2 2 2
2 2 2 2
L3 (物理的
L3 (物理的
に分散)
に分散)
メインメモリ
…
メモリ階層が階層
InfiniBand-EDR
ネットワーク
(12.5Gバイト/秒
×双方向)
12
スパコンプログラミング(1)、(Ⅰ)
Reedbush-U計算ノードの構成
1ソケットのみを図示(もう1ソケットある)
Core
#0
L L
1 2
L3
Core
#5
Core
#1
L L
1 2
L3
Core
#6
L L
1 2
Core
#2
L L
1 2
L3
Core
#7
L L
1 2
Core
#3
L L
1 2
L3
Core
#8
L L
1 2
Core
#4
L L
1 2
L3
DDR4
DIMM
Memory
16GB ×2枚
コア当たりL1データ: 32KB, L2: 256KB,
L3: 2.5MB(共有) => L3 は全体で45MB
PCIe
QPI x2
L L
1 2
L3
Core
#9
L L
1 2
L3
Core
#14
L L
1 2
L3
L3
Core
#10
L L
1 2
L3
Core
#15
L L
1 2
L3
L3
Core
#11
L L
1 2
L3
Core
#16
L L
1 2
L3
L3
Core
#12
L L
1 2
L3
Core
#17
L L
1 2
L3
Core
#13
L L
1 2
L3
Memory
16GB ×2枚
ソケット当たりメモリ量:16GB×8=128GB
Memory
Memory
16GB ×2枚
16GB ×2枚
76.8 GB/秒
=(8Byte×2400MHz×4 channel)
スパコンプログラミング(1)、(Ⅰ)
13
Reedbush-UのCPU(Xeon E5-2695v4)の
詳細情報
項目
命令セット
動作周波数
L1キャッシュ
L2キャッシュ
L3キャッシュ
演算実行
SIMD命令実行
レジスタ
値
IA32 64bit 拡 張 命 令 + AVX2 (Advanced Vector
eXtensions 2)
2.1 GHz
32 Kbytes (命令、データは分離、コア単位)
256 Kbytes (コア単位)
45 Mbytes (ソケット単位)
2整数演算ユニット、2つの浮動小数点積和演算ユニット(FMA)
1命令で4つのFMAが動作
FMAは2つの浮動小数点演算(加算と乗算)を実行可能
l 浮動小数点レジスタ数:16本(物理的には168本?)
スパコンプログラミング(1)、(Ⅰ)
演算パイプライン
演算の流れ作業
14
スパコンプログラミング(1)、(Ⅰ)
15
流れ作業
車を作る場合
• 1人の作業員が1つの工程を担当(5名)
•
フロント・バッ
クガラスを
つける
車体作成
•
内装
外装
機能確認
上記工程が2ヶ月だとする(各工程は0.4ヶ月とする)
• 2ヶ月後に1台できる
• 各工程の作業員は、
• 4ヶ月後に2台できる
0.4ヶ月働いて、
1.6ヶ月は休んでいる
(=作業効率が低い)
• 2ヶ月/台 の効率
1台目
2台目
3台目
車体作成
フロント・
バックガ
ラスをつ
ける
内装
外装
機能確
認
車体作成
フロント・
バックガ
ラスをつ
ける
内装
外装
機能確
認
車体作成
フロント・
バックガ
ラスをつ
ける
内装
外装
機能確
認
時間
16
スパコンプログラミング(1)、(Ⅰ)
流れ作業
作業場所が5ヶ所とれるとする
• 前の工程からくる車を待ち、担当工程が終わったら、
次の工程に速やかに送られるとする
•
• ベルトコンベア
0.4ヶ月
車体作成
0.4ヶ月
フロント・バック
ガラスをつける
0.4か月
内装
0.4か月
外装
0.4か月
機能確認
スパコンプログラミング(1)、(Ⅰ)
17
流れ作業
•
•各作業員は、
十分に時間が経つと
0.4か月の単位時間あたり
休むことなく働いている
(=作業効率が高い)
この方法では
• 2ヶ月後に、1台できる
• 2.4ヶ月後に、2台できる
• 2.8ヶ月後に、3台できる
• 3.2ヶ月後に、4台できる
• 3.4ヶ月後に、5台できる
• 3.8ヶ月後に、6台できる
•このような処理を、
<パイプライン処理>
という
• 0.63ヶ月/台 の効率
1台目
2台目
3台目
4台目
5台目
車体作成
フロント・
バックガ
ラスをつ
ける
車体作成
内装
外装
機能確
認
フロント・
バックガ
ラスをつ
ける
内装
外装
機能確
認
フロント・
バックガ
ラスをつ
ける
内装
外装
車体作成
車体作成
フロント・
バックガ
ラスをつ
ける
車体作成
機能確
認
内装
外装
機能確
認
フロント・
バックガ
ラスをつ
ける
内装
外装
機能確
認
時間
スパコンプログラミング(1)、(Ⅰ)
18
計算機におけるパイプライン処理の形態
ハードウエア・パイプライニング
1.
計算機ハードウエアで行う
以下の形態が代表的
•
•
1.
2.
演算処理におけるパイプライン処理
メモリからのデータ(命令コード、データ)転送における
パイプライン処理
ソフトウエア・パイプライニング
2.
プログラムの書き方で行う
以下の形態が代表的
•
•
1.
2.
コンパイラが行うパイプライン処理
(命令プリロード、データ・プリロード、データ・ポストストア)
人手によるコード改編によるパイプライン処理
(データ・プリロード、ループアンローリング)
19
スパコンプログラミング(1)、(Ⅰ)
演算器の場合
•
例:演算器の工程(注:実際の演算器の計算工程は異なる)
データAを
メモリから取る
データBを
メモリから取る
演算
を行う
演算結果を
収納
行列-ベクトル積の計算では
for (j=0; j<n; j++)
演算器が稼働
for (i=0; i<n; i++) {
する工程
y[j] += A[j][i] * x[i] ;
}
• パイプライン化しなければ以下のようになり無駄
•
A[0][0]を
メモリから取る
x[0]をメモリから
取る
A[0][0]*
x[0]
結果
y[0]収納
A[0][1]を
メモリから取る
x[1]をメモリから
取る
A[0][0]*
x[1]
結果
y[0]収納
A[0][2]を
メモリから取る
時間
x[2]をメモリから
取る
20
スパコンプログラミング(1)、(Ⅰ)
演算器の場合
先ほどの例では演算器は、4単位時間のうち、1単位時間し
か使われていないので無駄(=演算効率1/4=25%)
• 以下のようなパイプライン処理ができれば、
十分時間が経つと、毎単位時間で演算がなされる
l十分な時間とは、十分な
(=演算効率100%)
•
A[0][0]を
メモリから取る
x[0]をメモリから
取る
A[0][1]を
メモリから取る
A[0][0]*
x[0]
結果
y[0]収納
x[1]をメモリから
取る
A[0][0]*
x[1]
結果
y[0]収納
x[2]をメモリから
取る
A[0][2]*
x[2]
A[0][2]を
メモリから取る
A[0][3]を
メモリから取る
x[3]をメモリから
取る
A[0][4]を
メモリから取る
結果
y[0]収納
ループ反復回数があること。
行列サイズNが大きいほど、
パイプラインが滞りなく流れ、
演算効率は良くなる。
→Nが小さいと演算効率
が悪い
A[0][3]*
x[3]
結果
y[0]収納
x[4]をメモリから
取る
A[0][2]*
x[4]
…
結果
y[0]収納
時間
スパコンプログラミング(1)、(Ⅰ)
21
演算パイプラインのまとめ
演算器をフル稼働させるため(=高性能計算するため)に必
要な概念
• メインメモリからデータを取ってくる時間はとても大きい。
演算パイプラインをうまく組めば、メモリからデータを
取ってくる時間を<隠ぺい>できる
(=毎単位時間、演算器が稼働した状態にできる)
• 実際は以下の要因があるので、そう簡単ではない
•
1.
2.
3.
計算機アーキテクチャの構成による遅延(レジスタ数の制約、
メモリ→CPU・CPU→メモリへのデータ供給量制限、など)。
ループに必要な処理(ループ導入変数(i, j)の初期化と加算処理、
ループ終了判定処理)
配列データを参照するためのメモリアドレスの計算処理
コンパイラが正しくパイプライン化される命令を生成するか
スパコンプログラミング(1)、(Ⅰ)
22
実際のプロセッサの場合
• 実際のプロセッサでは
1. 加減算
2. 乗算
ごとに独立したパイプラインがある。
• さらに、同時にパイプラインに流せる命令
(同時発行命令)が複数ある。
• Intel Pentium4ではパイプライン段数が31段
• 演算器がフル稼働になるまでの時間が長い。
• 分岐命令、命令発行予測ミスなど、パイプラインを中断させる処理が多発す
ると、演算効率がきわめて悪くなる。
• 近年の周波数の低い(低電力な)マルチコアCPU/メニーコアCPUでは、パ
イプライン段数が少なくなりつつある(Xeon Phiは7段)
• Broadwellでは 14-19段 (?)
スパコンプログラミング(1)、(Ⅰ)
23
Reedbush-Uのハードウエア情報
•
1クロックあたり、16回の演算ができる
• AVX2ユニットあたり、乗算および加算 が4つ
(8つの浮動小数点演算)
• 1クロックで、2つのAVX2ユニットが動作
• 8浮動小数点演算×2 AVX2ユニット=16浮動小数点演算/クロック
•
1コア当たり2.1GHzのクロックなので、
• 理論最大演算は、
2.1 GHz* 16回 = 33.6 GFLOPS / コア
• 1ノード36コアでは、
33.6 * 36コア = 1209.6 GFLOPS / ノード
スパコンプログラミング(1)、(Ⅰ)
ループアンローリング
コンパイラがやりそうでなかなかやらないんだな
24
スパコンプログラミング(1)、(Ⅰ)
25
ループアンローリング
• コンパイラが、
1. レジスタへのデータの割り当て;
2. パイプライニング;
がよりできるようにするため、コードを書き
換えるチューニング技法
• ループの刻み幅を、1ではなく、mにする
• <m段アンローリング>とよぶ
スパコンプログラミング(1)、(Ⅰ)
26
ループアンローリング
• コンパイラ用語では、最内側のループの
展開のこと
• 狭義のループアンローリング
• アプリ屋さんは、多重ループのどの
ループでも展開することをいう
• 広義のループアンローリング
• もしくはコンパイラ用語で、
ループリストラクチャリング(ループ再構成)
の一種
スパコンプログラミング(1)、(Ⅰ)
27
ループアンローリングの例
(行列-行列積、C言語)
lk-ループ2段展開 (nが2で割り切れる場合)
for (i=0; i<n; i++)
for (j=0; j<n; j++)
for (k=0; k<n; k+=2)
C[i][j] += A[i][k] *B[k][j] + A[i][k+1]*B[k+1][j];
Øk-ループのループ判定回数が1/2になる。
スパコンプログラミング(1)、(Ⅰ)
28
ループアンローリングの例
(行列-行列積、C言語)
lj-ループ2段展開
(nが2で割り切れる場合)
for (i=0; i<n; i++)
for (j=0; j<n; j+=2)
for (k=0; k<n; k++) {
C[i][j ] += A[i][k] *B[k][j ];
C[i][j+1] += A[i][k] *B[k][j+1];
}
ØA[i][k]をレジスタに置き、高速にアクセスできるようになる。
スパコンプログラミング(1)、(Ⅰ)
29
ループアンローリングの例
(行列-行列積、C言語)
li-ループ2段展開
(nが2で割り切れる場合)
for (i=0; i<n; i+=2)
for (j=0; j<n; j++)
for (k=0; k<n; k++) {
C[i ][j] += A[i ][k] *B[k][j];
C[i+1][j] += A[i+1][k] *B[k][j];
}
ØB[i][j]をレジスタに置き、高速にアクセスできるようになる。
スパコンプログラミング(1)、(Ⅰ)
ループアンローリングの例
(行列-行列積、C言語)
li-ループ、および
j-ループ 2段展開
(nが2で割り切れる場合)
for (i=0; i<n; i+=2)
for (j=0; j<n; j+=2)
for (k=0; k<n; k++) {
C[i ][j ] += A[i ][k] *B[k][j ];
C[i ][j+1] += A[i ][k] *B[k][j+1];
C[i+1][j ] += A[i+1][k] *B[k][j ];
C[i+1][j+1] += A[i+1][k] *B[k][j +1];
}
ØA[i][j], A[i+1][k],B[k][j],B[k][j+1]をレジスタに置き、
高速にアクセスできるようになる。
30
スパコンプログラミング(1)、(Ⅰ)
31
ループアンローリングの例
(行列-行列積、C言語)
lコンパイラにわからせるため、以下のように書く方がよい
場合がある
for (i=0; i<n; i+=2)
for (j=0; j<n; j+=2) {
dc00 = C[i ][j ]; dc01 = C[i ][j+1];
dc10 = C[i+1][j ]; dc11 = C[i+1][j+1] ;
for (k=0; k<n; k++) {
da0= A[i ][k] ; da1= A[i+1][k] ;
db0= B[k][j ]; db1= B[k][j+1];
dc00 += da0 *db0; dc01 += da0 *db1;
dc10 += da1 *db0; dc11 += da1 *db1;
}
C[i ][j ] = dc00; C[i ][j+1] = dc01;
C[i+1][j ] = dc10; C[i+1][j+1] = dc11;
}
スパコンプログラミング(1)、(Ⅰ)
ループアンローリングの例
(行列-行列積、Fortran言語)
lk-ループ2段展開 (nが2で割り切れる場合)
do i=1, n
do j=1, n
do k=1, n, 2
C(i, j) = C(i, j) +A(i, k) *B(k, j) + A(i, k+
1)*B(k+1, j)
enddo
enddo
enddo
Øk-ループのループ判定回数が1/2になる。
32
スパコンプログラミング(1)、(Ⅰ)
33
ループアンローリングの例
(行列-行列積、Fortran言語)
lj-ループ2段展開
(nが2で割り切れる場合)
do i=1, n
do j=1, n, 2
do k=1, n
C(i, j ) = C(i, j ) +A(i, k) * B(k, j )
C(i, j+1) = C(i, j+1) +A(i, k) * B(k, j+1)
enddo
enddo
enddo
ØA(i,
k)をレジスタに置き、高速にアクセスできるようになる。
スパコンプログラミング(1)、(Ⅰ)
34
ループアンローリングの例
(行列-行列積、Fortran言語)
li-ループ2段展開
(nが2で割り切れる場合)
do i=1, n, 2
do j=1, n
do k=1, n
C(i , j) = C(i , j) +A(i , k) * B(k , j)
C(i+1, j) = C(i+1, j) +A(i+1, k) * B(k , j)
enddo
enddo
enddo
ØB(i,
j)をレジスタに置き、高速にアクセスできるようになる。
スパコンプログラミング(1)、(Ⅰ)
35
ループアンローリングの例
(行列-行列積、Fortran言語)
li-ループ、および j-ループ 2段展開
(nが2で割り切れる場合)
do i=1, n, 2
do j=1, n, 2
do k=1, n
C(i , j ) = C(i , j ) +A(i , k) *B(k, j )
C(i , j+1) = C(i , j+1) +A(i , k) *B(k, j+1)
C(i+1, j ) = C(i+1, j ) +A(i+1, k) *B(k, j )
C(i+1, j+1) =C(i+1, j+1) +A(i+1, k) *B(k, j +1)
enddo; enddo; enddo;
ØA(i,j), A(i+1,k),B(k,j),B(k,j+1)をレジスタに置き、
高速にアクセスできるようになる。
スパコンプログラミング(1)、(Ⅰ)
36
ループアンローリングの例
(行列-行列積、Fortran言語)
lコンパイラにわからせるため、以下のように書く方がよい
場合がある
l do i=1, n, 2
do j=1, n, 2
dc00 = C(i ,j ); dc01 = C(i ,j+1)
dc10 = C(i+1,j ); dc11 = C(i+1,j+1)
do k=1, n
da0= A(i ,k); da1= A(i+1, k)
db0= B(k ,j ); db1= B(k, j+1)
dc00 = dc00+da0 *db0; dc01 = dc01+da0 *db1;
dc10 = dc10+da1 *db0; dc11 = dc11+da1 *db1;
enddo
C(i , j ) = dc00; C(i , j+1) = dc01
C(i+1, j ) = dc10; C(i+1, j+1) = dc11
enddo; enddo
スパコンプログラミング(1)、(Ⅰ)
配列連続アクセス
とびとびアクセスには弱い
37
38
スパコンプログラミング(1)、(Ⅰ)
配列の格納方式
• C言語の場合
}
A[i][j]
Fortran言語の場合
A(i, j)
j
j
1
2
3
4
1
5
9
13
5
6
7
8
2
6
10
14
9
10
11
12
3
7
11
15
13
14
15
16
4
8
12
16
格納方向
i
i
格納方向
39
スパコンプログラミング(1)、(Ⅰ)
キャッシュとキャッシュライン
•
メインメモリ上とキャッシュ上のデータマッピング方式
• メインメモリからキャッシュへ
• ダイレクト・マッピング方式: 単位(メモリバンク)ごとに直接的
• セット・アソシアティブ方式: ハッシュ関数で写像する(間接的)
• キャッシュからメインメモリへ
• ストア・スルー方式: キャッシュ書き込み時に
メインメモリと中身を一致させる
• ストア・イン方式: 対象となる単位(キャッシュライン)
が置き換え対象となったときに一致させる
キャッシュメモリ
キャッシュ
ライン
ライン0
ライン1
ライン2
ライン3
ライン4
ライン5
…
メインメモリ
写像関数
メモリバンク
…
40
スパコンプログラミング(1)、(Ⅰ)
キャッシュライン衝突
• 直接メインメモリのアドレスをキャッシュに写像する
簡単なダイレクト・マッピングを考える
• このマッピングの間隔を、ここでは、4とする
• メインメモリ上のデータは、間隔4ごとに、同じキャッシュラインにのる
• この例で、格納方向と逆方向に連続アクセスする
(=C言語の場合、i方向を連続アクセス)
メインメモリ
キャッシュ
ライン
メモリ連続
キャッシュメモリ
ライン0
ライン1
ライン2
ライン3
1
5
9
13
配列アクセス方向
2
6
10
14
…
3
7
11
15
4
8
12
16
41
スパコンプログラミング(1)、(Ⅰ)
キャッシュライン衝突
この場合、データ1がキャッシュライン0に乗ったあと、
すぐにデータ5がアクセスされるため、
キャッシュライン0のデータを追い出さないといけない
2. 同様に、データ5がキャッシュライン0に乗ったあと、
すぐにデータ9がアクセスされるため、
キャッシュライン0のデータを追い出さないといけない
1.
メインメモリ
キャッシュ
ライン
レジスタへ
キャッシュメモリ
9
5
1
ライン0
ライン1
ライン2
ライン3
1
5
9
13
2
6
10
14
…
配列アクセス方向
3
7
11
15
メモリ連続
4
8
12
16
スパコンプログラミング(1)、(Ⅰ)
42
キャッシュライン衝突
• 以上の、1、2の状態が連続して発生する。
• メモリ→キャッシュの回線が詰まっている
(お話し中状態で待たされる)
• メモリからデータを逐次で読み出しているの
と同じになる。
• キャッシュがないのと同じ。
• 演算器にデータが高速に届かず、演算パイプラインが
中断し、演算器の利用効率が悪くなる。
• 以上の現象を、(キャッシュの)<スラッシング>、
<キャッシュライン衝突>、<キャッシュ合同>
スパコンプログラミング(1)、(Ⅰ)
43
メモリインターリービング
物理的なメモリの格納方向に従いアクセスする場合
• データのアクセス時、現在アクセス中のメモリ上の管理
単位(バンク)上のデータは、周辺バンク上のデータも
一括して同一キャッシュライン上に乗せる機能がある
• ライン0のデータをアクセスしている最中に、ライン1中に
近隣のバンク内データを(並列に)持ってくることが可能
•
• メモリの<インタリービング>
• 演算機から見た場合、データアクセス時間の短縮になる
• 演算器が遊ぶ時間が少なくなる(=演算効率が高くなる)
物理的なデータ格納方向に連続アクセスする
ループ構成にする
スパコンプログラミング(1)、(Ⅰ)
44
キャッシュライン衝突が起こる条件
• キャッシュラインへのメモリバンク割り付けは、
2冪の間隔で行っていることが多い
• たとえば、32、64、128など
• 特定サイズの問題(たとえば、1024次元)で、
性能が1/2~1/3、ときには1/10になる
場合、キャッシュライン衝突が生じている
可能性が高い。
• 実際はもっと複雑なので、厳密な条件を見つける
ことは難しいが
2冪サイズでの配列確保は避けるべき
スパコンプログラミング(1)、(Ⅰ)
45
キャッシュライン衝突への対応
• キャッシュライン衝突が生じた場合防ぐ方法は以下
(このサイズの計算を避けるという自明な解以外)
1. パティング法: 配列に(2冪でない)余分な領域を確
保し確保配列の一部の領域を使う。
•
•
余分な領域を確保したうえで、(&A)++;など
コンパイラによるオプション在り
2. データ圧縮法: 計算に必要なデータのみ、
新しい配列をキャッシュライン衝突しないように
確保し、必要なデータを移す。
3. 予測計算法: キャッシュライン衝突が起こる回数を
予測するルーチンを埋め込み、そのルーチンを
配列確保時に呼ぶことで対応。
スパコンプログラミング(1)、(Ⅰ)
46
FX10特有の回避法
• Sparc64 Ivfxでは、L1キャッシュラインは2Wayのため、
キャッシュライン衝突が起こりやすい
• 特に、OpenMPなど、スレッド実行時には、起こる確率が増す
• そこで、OpenMPのスレッド実行の方法を、Staticから
Dynamic(Cyclic)にすることで、隣のコアがL2にロードした情報を再
利用し、L1キャッシュライン衝突を防げることが報告されている。
• !$OMP DO SCHEDULE(static,1)
• 参考
• 理化学研究所 次世代スーパコンピュータ開発実施本部 開発グループ アプ
リケーション開発チーム 南 一生 氏
「スーパーコンピュータ「京」におけるアプリケーションの高並列化と高性能
化」、SACSIS2012チュートリアル資料
http://sacsis.hpcc.jp/2012/files/SACSIS2012-tutorial1-pub.pdf
スパコンプログラミング(1)、(Ⅰ)
47
サンプルプログラムの実行
(行列-行列積)
スパコンプログラミング(1)、(Ⅰ)
48
UNIX備忘録
• emacsの起動: emacs 編集ファイル名
• ^x ^s (^はcontrol) :テキストの保存
• ^x ^c : 終了
( ^z で終了すると、スパコンの負荷が上がる。絶対にしないこと。)
^g : 訳がわからなくなったとき。
• ^k : カーソルより行末まで消す。
消した行は、一時的に記憶される。
• ^y : ^kで消した行を、現在のカーソルの場所にコピーする。
• ^s 文字列 : 文字列の箇所まで移動する。
• ^M x goto-line : 指定した行まで移動する。
•
スパコンプログラミング(1)、(Ⅰ)
49
UNIX備忘録その2
• rm ファイル名: ファイル名のファイルを消す。
• rm *~ : test.c~ などの、~がついたバックアップファイルを消す。使う時は
慎重に。*~ の間に空白が入ってしまうと、全てが消えます。
• ls : 現在いるフォルダの中身を見る。
• cd フォルダ名: フォルダに移動する。
• cd .. : 一つ上のフォルダに移動。
• cd ~ :ホームディレクトリに行く。訳がわからなくなったとき。
• cat ファイル名: ファイル名の中身を見る
• make : 実行ファイルを作る
(Makefile があるところでしか実行できない)
• make clean : 実行ファイルを消す。
(clean がMakefileで定義されていないと実行できない)
スパコンプログラミング(1)、(Ⅰ)
50
UNIX備忘録その3
• less ファイル名: ファイル名の中身を見る(catでは
画面がいっぱいになってしまうとき)
• スペースキー : 1画面スクロール
• / : 文字列の箇所まで移動する。
• q : 終了 (訳がわからなくなったとき)
スパコンプログラミング(1)、(Ⅰ)
51
行列-行列積のサンプルプログラムの注意点
• C言語版およびFortran言語版のファイル名
Mat-Mat-noopt-rb.tar
• ジョブスクリプトファイルmat-mat-noopt.bash
中のキュー名を u-lecture から
u-lecture5 (工学部共通科目)
に変更してから qsub してください。
• u-lecture : 実習時間外のキュー
• u-ecture5: 実習時間内のキュー
スパコンプログラミング(1)、(Ⅰ)
52
行列-行列積のサンプルプログラムの実行
(C言語版、Fortran言語でも同様)
以下のコマンドを実行する
$ cp /lustre/gt15/z30105/Mat-Mat-noopt-rb.tar ./
$ tar xvf Mat-Mat-noopt-rb.tar
$ cd Mat-Mat-noopt
• 以下のどちらかを実行
$ cd C : C言語を使う人
$ cd F : Fortran言語を使う人
• 以下は共通
$ make
$ qsub mat-mat-noopt.bash
• 実行が終了したら、以下を実行する
$ cat mat-mat-noopt.bash.oXXXX (XXXXは数字)
•
スパコンプログラミング(1)、(Ⅰ)
53
行列-行列積のサンプルプログラムの実行
• 以下のような結果が見えれば成功
(Fortran言語の場合)
N = 512
Mat-Mat time[sec.] =
1.41415309906006
MFLOPS = 189.820646364729
スパコンプログラミング(1)、(Ⅰ)
54
行列-行列積のサンプルプログラムの実行
• 以下のような結果が見えれば成功
(C言語の場合)
N = 512
Mat-Mat time = 1.243629 [sec.]
215.848505 [MFLOPS]
OK!
スパコンプログラミング(1)、(Ⅰ)
55
サンプルプログラムの説明(C言語)
• #define N
512
の、数字を変更すると、行列サイズが変更
できます
• #define DEBUG 1
「1」にすると、行列-行列積の演算結果が
検証できます。
• MyMatMat関数の仕様
• Double型N×N行列AとBの行列積をおこない、
Double型N×N行列Cにその結果が入ります
スパコンプログラミング(1)、(Ⅰ)
56
Fortran言語のサンプルプログラムの注意
• 行列サイズNNの宣言は、以下のファイルにあ
ります。
mat-mat-noopt.inc
• 行列サイズ変数が、NNとなっています。
integer NN
parameter (NN=512)
スパコンプログラミング(1)、(Ⅰ)
57
演習課題
• MyMatMat関数(手続き)を、アンローリングな
どにより高速化してください
• どういうアンローリングの仕方がよいか、
最も高速となる段数、などを調べてください。
• コンパイラの最適化レベルを0にしてあります。
本演習では、最適化レベルをとりあえず0で固定
しておいてください。
• コンパイラによる最適化を行い、かつ手による
アンローリングしてもよいのですが、場合により
アンローリングの効果がなくなります。
スパコンプログラミング(1)、(Ⅰ)
58
レポート課題
[L10] 行列-行列積について、メモリ連続アクセスとな
る場合と、不連続となる場合の性能を調査せよ。
2. [L15] 行列-行列積のアンローリングを、i, j, k ループ
について施し、性能向上の度合いを調べよ。どのアン
ローリング方式や段数が高速となるだろうか。
1.
問題のレベルに関する記述:
•L00: きわめて簡単な問題。
•L10: ちょっと考えればわかる問題。
•L20: 標準的な問題。
•L30: 数時間程度必要とする問題。
•L40: 数週間程度必要とする問題。複雑な実装を必要とする。
•L50: 数か月程度必要とする問題。未解決問題を含む。
※L40以上は、論文を出版するに値する問題。
スパコンプログラミング(1)、(Ⅰ)
59
参考文献(最適化全体)
1. 寒川光、「RISC超高速化プログラミング技
法」、共立出版、ISBN4-320-02750
-7、3,500円
2. Kevin Dowd著、久良知真子訳、「ハイ・パ
フォーマンス・コンピューティング:RISCワー
クステーションで最高の性能を引き出すため
の方法」、インターナショナル・トムソン・パブ
リッシング・ジャパン、ISBN4-900718-
03-3、4,400円
スパコンプログラミング(1)、(Ⅰ)
来週へつづく
高性能プログラミング技法の基礎(2)
60