第4回 配信講義 計算科学技術特論B (2024)

1.4K Views

May 02, 24

スライド概要

--------------------------------------------------------------
第4回 5月9日 アプリケーションの性能最適化2
(CPU単体性能最適化)
---------------------------------------------------------------
第4回は,「CPU単体性能」についての第3回での講義内容をふまえ、「CPU単体性能」を出すために留意しておくべき事項。ノード内・CPU内・コア内の並列処理並びにメモリアクセスについて紹介する。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

計算科学特論B 第4回 アプリケーションの性能最適化2 (CPU単体性能最適化) ジャパンメディカルデバイス株式会社 熊畑 清 2024.5.9(⽊)

2.

講義の概要 • 4⽉11⽇ スーパーコンピュータとアプリケーションの性能 • 4⽉18⽇ アプリケーションの性能最適化1(⾼並列性能最適化) • 4⽉25⽇ アプリケーションの性能最適化の実例1とCPU単体性能とは︖ • 5⽉9⽇ アプリケーションの性能最適化2(CPU単体性能最適化) • 5⽉16⽇ アプリケーションの性能最適化の実例2 2

3.

並列性能と、CPU単体性能 並列性能 CPU単体性能 CPU単体性能とは、読んで字のごとく、⼀つのCPUだ けに着⽬した性能 速度向上率 s(p) CPU1台の時と⽐べて何倍か︖ に ら た し が1 0倍 ) 性 能 0倍 して 1 に 0倍 Uを 1 P を うC PU C 使 う ( (使 想 実 理 現 が 能 も性 にな 倍 10 ら ) ない 多くは、pの増⼤に 伴って「鈍る」 p=使うCPU数 1 CPUでの実⾏時間はT1 p CPUでの実⾏時間をT(p) S(p) = T1 / T(p) 例) たくさんの荷物を、何台かの⾞で分担 して運びたい • なるべく⼤きな⾞を⽤意したい • なるべくたくさん⾞を⽤意したい • なるべく効率よく荷物を積みたい こっちの観点 本⽇はCPU単体性能をより良くするために、考えないと いけないことを紹介 3

4.

並列処理の様々なレベル

5.

並列のレベル • 第1回の講義で並列処理について紹介があった • 並列処理にはハード的にどう⾔うレベルで⾏うかに応じて種類がある • MPI並列(分散メモリ) CPU Memory Storage CPU I.C.C Memory Storage CPU I.C.C Memory I.C.C Storage 5

6.

並列のレベル • 第1回の講義で並列処理について紹介があった • 並列処理にはハード的にどう⾔うレベルで⾏うかに応じて種類がある • スレッド並列(共有メモリ) Core Core Core Core ・・・ Core Cache Memory 6

7.

並列のレベル • 第1回の講義で並列処理について紹介があった • 並列処理にはハード的にどう⾔うレベルで⾏うかに応じて種類がある • コア内の並列(命令レベル並列) 演算器 演算器 Register Register Cache 単体性能(=通信をしない処理)の向上 には • スレッド並列 • コア内の並列 • メモリ・キャッシュ・レジスタ間のデータ転送 が重要 7

8.

本⽇の内容 • 単体性能のおはなし • スレッド並列 • プロファイラ(CPU性能解析レポート) • リカレンスの除去とカラーリング • コア内の並列性、演算命令とスケジュール • SIMD • ソフトウェアパイプライニング • メモリ・キャッシュ・レジスタ間のデータ転送 • キャッシュのアクセス効率化 • ラインアクセス • キャッシュスラッシングとFalse Sharing • ストリームの考え⽅とZ-Fill • プリフェッチ 8

9.

スレッド並列

10.

スレッド並列 • スレッド並列(共有メモリ) • ⼀つのCPU(プロセス)内で仕事を分担して並列処理 • 通信はしないが、コア間の情報交換は必要で、前回の⾼並列性能最適化と同様にリカレンス (データの依存性)を気にしないといけない Core Core Core Core ・・・ Core Cache Memory 10

11.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 DO IE=1,NE IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) を計算するループ Ñp = 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) ¶N j ¶p @å pe ¶xi j =1 ¶xi 内容 節点リスト 圧力 形状関数の導関数 圧力勾配ベクトル FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO 11

12.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) 内容 節点リスト 圧力 を計算するループ Ñp = ¶N j ¶p @å pe ¶xi j =1 ¶xi 形状関数の導関数 圧力勾配ベクトル 1 2 3 4 5 6 7 8 12

13.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) を計算するループ 内容 節点リスト 圧力 Ñp = ¶N j ¶p @å pe ¶xi j =1 ¶xi 形状関数の導関数 圧力勾配ベクトル 2 3 頂点番号 1 要素番号4 2 要素番号5 4 6 要素番号6 3 2=NODE(1,5) 3=NODE(2,5) 7=NODE(3,5) 6=NODE(4,5) 7 13

14.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) を計算するループ 内容 節点リスト 圧力 Ñp = ¶N j ¶p @å pe ¶xi j =1 ¶xi 形状関数の導関数 圧力勾配ベクトル S(4) S(5) S(6) 14

15.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) DNX(1,4) Ñp = ¶N j ¶p @å pe ¶xi j =1 ¶xi 形状関数の導関数 圧力勾配ベクトル DNX(2,4) 要素番号4 DNX(4,4) を計算するループ 内容 節点リスト 圧力 DNX(3,4) DNX(1,5) DNX(2,5) 要素番号5 DNX(4,4) DNX(3,4) DNX(1,6) DNX(2,6) 要素番号6 DNX(4,6) DNX(3,6) 15

16.

リカレンス(データの依存性) ある有限要素法の流体解析プログラム 4角形要素について∇pの有限要素近似 型 配列名とサイズ INTEGER*4 NODE(9,NE) REAL*4 S(NE) DNX(9,NE), DNY(9,NE), REAL*4 DNZ(9,NE) REAL*4 FX(NP), FY(NP), FZ(NP) 内容 節点リスト 圧力 を計算するループ Ñp = ¶N j ¶p @å pe ¶xi j =1 ¶xi 形状関数の導関数 圧力勾配ベクトル FX(1) FX(2) FX(3) FX(4) FX(5) FX(6) FX(7) FX(8) 16

17.

リカレンス(データの依存性) このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を 掛け合わせた値を、頂点に対応する節点に⾜し込む DO IE=1,NE IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO FX(1) FX(2) S(4)*DNX(1,4) S(4)*DNX(2,4) S(4)*DNX(4,4) S(4)*DNX(3,4) FX(5) FX(6) FX(3) FX(4) FX(7) FX(8) 17

18.

リカレンス(データの依存性) このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を 掛け合わせた値を、頂点に対応する節点に⾜し込む DO IE=1,NE IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) FX(1) SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO FX(5) FX(2) FX(3) S(4)*DNX(1,5) S(4)*DNX(2,5) S(4)*DNX(4,5) S(4)*DNX(3,5) FX(6) FX(7) FX(4) FX(8) 18

19.

リカレンス(データの依存性) このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を 掛け合わせた値を、頂点に対応する節点に⾜し込む DO IE=1,NE IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) FX(1) FX(2) SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO FX(5) FX(6) FX(3) FX(4) S(4)*DNX(1,6) S(4)*DNX(2,6) S(4)*DNX(4,6) S(4)*DNX(3,6) FX(7) FX(8) 19

20.

リカレンス(データの依存性) このループをスレッド並列すると、複数の要素を同時に処理することになるが そうすると、リカレンスが⽣じるためできない DO IE=1,NE IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) ここをスレッド並列 SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO FX(1) FX(2) FX(3) FX(4) S(4)*DNX(1,4) S(4)*DNX(2,4) S(4)*DNX(1,5) S(4)*DNX(2,5) S(4)*DNX(1,6) S(4)*DNX(2,6) S(4)*DNX(4,4) S(4)*DNX(3,4) S(4)*DNX(4,5) S(4)*DNX(3,5) S(4)*DNX(4,6) S(4)*DNX(3,6) FX(5) FX(6) FX(7) FX(8) 20

21.

スレッド並列のためのリカレンス除去 カラーリングを導⼊して、要素を互いに隣り合っていないカラー(グループ)に分ける 1 2 3 4 1 5 2 6 5 6 7 8 9 13 10 14 9 10 11 12 3 7 4 8 13 14 15 16 11 15 12 16 21

22.

スレッド並列のためのリカレンス除去 メモリ上ではカラー毎に連続になるよう必要に応じて要素番号を付け替える 1 2 3 4 1 5 2 6 5 6 7 8 9 13 10 14 9 10 11 12 3 7 4 8 13 14 15 16 11 15 12 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 カラー1 カラー2 カラー3 カラー4 START(1)=1 END(1)=4 START(2)=5 END(2)=8 START(3)=9 END(3)=12 START(4)=13 END(4)=16 22

23.

リカレンス(データの依存性) DO ICOLOR=1, NCOLOR ST=START(ICOLOR) ED=END(ICOLOR) DO IE=ST,ED IP1=NODE(1,IE) IP2=NODE(2,IE) IP3=NODE(3,IE) IP4=NODE(4,IE) ここをスレッド並列 SWRK=-S(IE) FX(IP1)=FX(IP1)+SWRK*DNX(1,IE) FX(IP2)=FX(IP2)+SWRK*DNX(2,IE) FX(IP3)=FX(IP3)+SWRK*DNX(3,IE) FX(IP4)=FX(IP4)+SWRK*DNX(4,IE) FY(IP1)=FY(IP1)+SWRK*DNY(1,IE) FY(IP2)=FY(IP2)+SWRK*DNY(2,IE) FY(IP3)=FY(IP3)+SWRK*DNY(3,IE) FY(IP4)=FY(IP4)+SWRK*DNY(4,IE) FZ(IP1)=FZ(IP1)+SWRK*DNZ(1,IE) FZ(IP2)=FZ(IP2)+SWRK*DNZ(2,IE) FZ(IP3)=FZ(IP3)+SWRK*DNZ(3,IE) FZ(IP4)=FZ(IP4)+SWRK*DNZ(4,IE) ENDDO ENDDO FX(1) FX(2) FX(3) FX(4) S(4)*DNX(1,4) S(4)*DNX(2,4) S(4)*DNX(1,6) S(4)*DNX(2,6) S(4)*DNX(4,4) S(4)*DNX(3,4) S(4)*DNX(4,6) S(4)*DNX(3,6) FX(5) FX(6) FX(7) FX(8) 23

24.

スレッド並列の実⾏形態 富岳,あるいはFX1000/FX700 CPU(=NODE) Core memory Group (CMG) 8 GiB Memory Core x12 Core x12 8 GiB Memory Core x12 8 GiB Memory リングバス 8 GiB Memory Core x12 A64FX 24

25.

スレッド並列の実⾏形態 富岳,あるいはFX1000/FX700 CPU(=NODE) Core memory Group (CMG) 8 GiB Memory Core x12 Core x12 8 GiB Memory Core x12 8 GiB Memory 1プロセス 12スレッド リングバス 8 GiB Memory Core x12 A64FX 25

26.

スレッド並列の実⾏形態 富岳,あるいはFX1000/FX700 CPU(=NODE) Core memory Group (CMG) 8 GiB Memory Core x12 Core x12 8 GiB Memory Core x12 8 GiB Memory 1プロセス 24スレッド リングバス 8 GiB Memory Core x12 A64FX 26

27.

スレッド並列の実⾏形態 富岳,あるいはFX1000/FX700 CPU(=NODE) Core memory Group (CMG) 8 GiB Memory Core x12 Core x12 8 GiB Memory Core x12 8 GiB Memory 1プロセス 48スレッド リングバス 8 GiB Memory A64FX Core x12 遠いメモリを使ってしまうかも 27

28.

スレッド並列の実⾏形態 Intelの計算機 NODE Memory (DDR4) Core x18 Xeon Gold 6240 UPI Memory (DDR4) Core x18 Xeon Gold 6240 28

29.

スレッド並列の実⾏形態 Intelの計算機だと NODE Memory (DDR4) Core x18 1プロセス 18スレッド Xeon Gold 6240 UPI Memory (DDR4) Core x18 Xeon Gold 6240 29

30.

スレッド並列の実⾏形態 Intelの計算機 NODE Memory (DDR4) Core x18 1プロセス 36スレッド Xeon Gold 6240 UPI Memory (DDR4) Core x18 Xeon Gold 6240 30

31.

スレッド並列の実⾏形態 Intelの計算機 NODE Memory (DDR4) Core x18 1プロセス 36スレッド Xeon Gold 6240 UPI 遠いメモリを使ってしまうかも Memory (DDR4) Core x18 Xeon Gold 6240 31

32.

スレッド並列の実⾏形態 Intelの計算機 NODE Memory (DDR4) Core x18 18プロセス 各1スレッド Xeon Gold 6240 プロセスそれぞれが使うメモリ UPI Memory (DDR4) Core x18 プロセスが増えると通信を管理 するためのメモリが増える Xeon Gold 6240 32

33.

推奨されるスレッド並列の実⾏形態 推奨の実⾏形態 Core memory Group (CMG) 8 GiB Memory Core x12 Core x12 8 GiB Memory 1プロセス 12スレッド Memory (DDR4) Core x18 1プロセス 18スレッド リングバス Xeon Gold 6240 8 GiB Memory Core x12 Core x12 8 GiB Memory UPI A64FX Memory (DDR4) Core x18 Xeon Gold 6240 33

34.

プロファイラの使⽤ 1/5 京/FX10/FX100でも使えたが、A64FX(富岳,FX1000/FX700)ではFAPPというプロファイラが 使える ソース中で、測定したい部分をサブルーチン・関数fapp_start/fapp_stopで挟み実⾏ファイルを、 プロファイラの実⾏コマンドから実⾏.実⾏後できたデータを変換してエクセルで読む. ソース例 (Fortran) call fapp_start("range", 1, 0) do i=0, N ・・・ call fapp_start("range", 2, 1) do j=0, M ・・・ enddo call fapp_stop("range", 2, 1) enddo call fapp_stop("range", 1, 0) 区間名 区間番号 レベル値 コンパイル例 (Fortran) frtpx source.f –Nfjprof –o a.out プロファイラ⽤のライブラリをリンクする指⽰ ただし指定しなくても、デフォルトで有効になっているので実 際には気にしなくて良い -Nnofjprofならリンクしない 34

35.
[beta]
プロファイラの使⽤ 2/5
京/FX10/FX100でも使えたが、A64FX(富岳,FX1000/FX700)ではFAPPというプロファイラが
使える
ソース中で、測定したい部分をサブルーチン・関数fapp_start/fapp_stopで挟み実⾏ファイルを、
プロファイラの実⾏コマンドから実⾏.実⾏後できたデータを変換してエクセルで読む.
ソース例 (C/C++)
fapp_start("range", 1, 0);
for(i=0; i<N+1; i++){
・・・
fapp_start("range", 2, 1);
for(j=0; j<M+1; j++){
・・・
}
fapp_stop("range", 2, 1);
}
fapp_stop("range", 1, 0);

区間名

区間番号

レベル値

コンパイル例 (C/C++)
fccpx source.cpp –Nfjprof –o a.out
プロファイラ⽤のライブラリをリンクする指⽰
ただし指定しなくても、デフォルトで有効になっているので実
際には気にしなくて良い
-Nnofjprofならリンクしない
※clangモードの場合は-ffj-fjprof あるいは
–fj-no-fjprof
35

36.

プロファイラの使⽤ 3/5 実⾏例(プロファイラのコマンドfappを介してa.outを呼ぶ) レベル指定 –L の例 for I in `seq 1 17` ←1, 5, 10, 17を指定 数が多いほど詳細な情報が取れる do fapp –C —Hevent=pa${I} -d ./pa${I} ¥ 本当は1⾏なので注意 -Icpupa –L0 a.out enddo call fapp_start("range", 1, 0) do i=0, N ・・・ call fapp_stop("range", 2, 1) do j=0, M ・・・ enddo call fapp_start("range", 2, 1) enddo call fapp_stop("range", 1, 0) -C 測定時のおまじない ⼀つのコマンドで複数の役割があるため) -Hevent=pa1〜17 測定するデータの種類を指定 -d 結果を出⼒するディレクトリ指定(-Heventの指定と合わせる) -Icpupa CPU内で起こる様々なイベントを測定する -L 0 測定のレベル指定 ソース中の、fapp_start/fapp_stop関数・サブルーチンで指定した レベル値が、ここでの指定値以下 (≦) のものを測定する -LNだとソース中のレベル指定の値が ≦ N で ある区間を測定する -L0だと⾚字の区間だけを測定 -L1だと⾚字と⻘字の区間を測定 36

37.

プロファイラの使⽤ 4/5 実⾏後は pa1~17のディレクトリができるので変換コマンドで読める形に変換する for I in `seq 1 17` do fapp –A -d ./pa${I} -Icpupa –tcsv –o pa${I}.csv enddo CPU Performance Analysis Report 4.2.1 Process no. -tcsv 変換結果をCSVで出⼒ peak ratio (GB/s) (%) Effective peak ratio instruction (%) SVE rate (%) operation (/Effective rate (%) operation pipeline Active Thread 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total (%) (%) 18.37% 17.90% 17.55% 16.92% 16.96% 16.93% 17.04% 16.96% 16.94% 16.91% 16.91% 16.90% 17.19% 15.28% 14.62% 14.34% 13.93% 13.95% 13.98% 13.87% 13.93% 13.84% 13.84% 13.83% 13.85% 14.11% L1I miss rate Cache (/Effective instruction) Process point busy rate instruction L1 busy rate L2 busy rate Memory busy (%) (%) rate (%) 1.06% 34.24% 33.22% 32.61% 31.60% 31.60% 31.60% 31.60% 31.58% 31.53% 31.60% 31.62% 31.61% 32.05% (%) 81.09% 80.49% 80.13% 79.49% 79.50% 79.50% 79.50% 79.49% 79.45% 79.48% 79.49% 79.49% 79.78% Process 88.95% 90.27% 90.99% 92.30% 92.36% 92.32% 92.32% 92.33% 92.23% 92.25% 92.25% 92.26% 91.71% 0.57 0.55 0.55 0.53 0.53 0.53 0.53 0.53 0.53 0.53 0.53 0.53 0.54 1.25 1.22 1.20 1.17 1.17 1.17 1.17 1.17 1.17 1.17 1.17 1.17 14.19 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total Integer operation pipeline B busy rate busy rate (%) (%) 5.03% 5.15% 5.05% 5.24% 5.35% 5.35% 5.34% 5.24% 4.90% 5.05% 5.10% 5.11% 5.16% 4.80% 4.73% 4.81% 4.58% 4.57% 4.56% 4.54% 4.71% 4.70% 4.56% 4.50% 4.57% 4.64% L1D miss 11.17% 11.08% 10.90% 10.68% 10.69% 10.69% 10.70% 10.67% 10.56% 10.61% 10.60% 10.60% 10.75% L1D miss rate (/Load- demand rate store (%) (/L1D instruction) miss) 0.69% 0.69% 1.06% 1.06% L1D miss L1D miss hardware software prefetch rate prefetch rate (%) (/L1D (%) (/L1D miss) miss) Address Address calculation calculation Floating- 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.45E+09 1.42E+09 1.41E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.38E+09 1.67E+10 point pipeline B Active Active operation pipeline B busy rate busy rate (%) (%) (%) (%) 12.29% 12.20% 11.91% 11.70% 11.80% 11.79% 11.84% 11.66% 11.37% 11.63% 11.69% 11.67% 11.80% 85.33% 86.50% 87.06% 88.08% 88.22% 88.14% 88.09% 88.17% 88.01% 87.94% 87.93% 87.94% 87.59% 93.30% 94.89% 95.79% 97.42% 97.39% 97.39% 97.51% 97.40% 97.41% 97.50% 97.52% 97.53% 96.72% 9.27% 9.22% 9.06% 9.11% 9.21% 9.21% 9.18% 9.08% 8.86% 9.01% 9.06% 9.03% 9.11% element rate element rate L2 miss rate L2 miss (/Load-store instruction) L2 miss demand rate (%) (/L2 miss) 4.40E+06 4.18E+06 5.06E+06 4.80E+06 3.74E+06 3.75E+06 3.75E+06 3.75E+06 3.79E+06 4.03E+06 3.82E+06 3.80E+06 4.89E+07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 23.42% 19.56% 33.91% 30.95% 10.42% 10.61% 10.72% 10.70% 12.00% 17.23% 12.35% 11.76% 17.82% 76.57% 80.47% 66.34% 68.71% 89.62% 89.41% 89.34% 89.33% 87.99% 82.71% 87.60% 88.26% 82.18% 0.01% -0.03% -0.25% 0.34% -0.03% -0.02% -0.07% -0.03% 0.01% 0.06% 0.06% -0.01% 0.00% 3.61E+06 3.54E+06 3.78E+06 3.46E+06 3.45E+06 3.45E+06 3.46E+06 3.46E+06 3.45E+06 3.45E+06 3.46E+06 3.45E+06 4.20E+07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.42% 4.42% 12.72% 10.19% 14.08% 11.93% 16.04% 4.00% 2.71% 2.55% 3.52% 13.89% 8.64% L1 pipeline 0 L1 pipeline 1 Active Active element rate element rate (%) (%) 98.81% 98.79% 98.75% 98.75% 98.77% 98.77% 98.78% 98.92% 99.29% 98.49% 98.42% 98.48% 98.75% 96.52% 96.92% 97.18% 97.58% 97.58% 97.58% 97.57% 97.40% 96.95% 97.82% 97.89% 97.84% 97.40% Thread 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 Single vector vector Non- contiguous contiguous contiguous structure gather load load instruction Hardware Prefetch Rate (%) (/Hardware Prefetch) Process instruction 1.64E+08 1.64E+08 1.64E+08 1.64E+08 1.64E+08 1.64E+08 1.64E+08 1.64E+08 1.63E+08 1.63E+08 1.63E+08 1.63E+08 1.96E+09 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 1.52E+08 1.47E+08 1.45E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.41E+08 1.71E+09 Broadcast load instruction 1.34E+08 1.14E+08 1.03E+08 8.46E+07 8.46E+07 8.46E+07 8.46E+07 8.46E+07 8.45E+07 8.45E+07 8.45E+07 8.45E+07 1.11E+09 L1 Injection Floatingpoint register fill instruction 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.13E+04 1.36E+05 Predicate Injection load load instruction instruction 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 6.00E+03 7.20E+04 mode Stream mode mode mode unallocate prefetch rate allocate unallocate 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% prefetch rate prefetch rate 46.72% 45.80% 43.57% 44.65% 41.12% 38.80% 45.84% 46.95% 46.96% 46.01% 47.03% 46.02% 44.96% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00E+00 7.36E+08 0.00E+00 7.32E+08 0.00E+00 7.29E+08 0.00E+00 7.25E+08 0.00E+00 7.25E+08 0.00E+00 7.25E+08 0.00E+00 7.25E+08 0.00E+00 7.25E+08 0.00E+00 7.24E+08 0.00E+00 7.24E+08 0.00E+00 7.24E+08 0.00E+00 7.24E+08 0.00E+00 8.72E+09 1.67E+10 Multiple L2 miss L2 miss hardware software prefetch rate prefetch rate (%) (/L2 (%) (/L2 miss) miss) 96.74% 97.02% 89.23% 91.00% 87.01% 89.30% 84.96% 97.17% 98.36% 98.78% 97.53% 87.18% 92.59% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% Floating- Integer load point load memory access wait memory access wait 4.92E-03 4.76E-03 4.59E-03 4.70E-03 4.78E-03 4.53E-03 4.70E-03 4.73E-03 4.65E-03 4.75E-03 4.83E-03 4.71E-03 4.72E-03 3.10E-03 2.50E-03 1.27E-02 1.34E-03 9.09E-04 6.40E-04 8.03E-04 8.89E-04 1.21E-03 8.62E-04 1.04E-03 6.11E-04 2.22E-03 Integer load Integer load L2 cache L1D cache access wait access wait 1.69E-03 1.23E-03 1.25E-03 1.30E-03 1.32E-03 1.27E-03 1.38E-03 1.35E-03 1.39E-03 1.41E-03 1.42E-03 1.42E-03 1.37E-03 4.01E-03 4.22E-03 4.15E-03 5.99E-03 4.13E-03 5.42E-03 5.50E-03 5.68E-03 5.27E-03 6.15E-03 4.61E-03 4.42E-03 4.96E-03 Operation wait Floating- Floatingpoint load L2 cache access wait point load Integer L1D cache operation access wait wait (*) 4.88E-03 3.18E-03 5.74E-03 5.73E-03 3.80E-04 3.73E-04 3.53E-04 6.25E-04 7.65E-04 1.86E-03 8.11E-04 6.96E-04 2.12E-03 6.94E-01 6.79E-01 6.62E-01 6.24E-01 5.94E-01 6.11E-01 6.12E-01 6.21E-01 6.46E-01 6.29E-01 6.26E-01 6.30E-01 6.36E-01 7.22E-02 6.64E-02 7.35E-02 6.03E-02 6.52E-02 6.78E-02 6.45E-02 6.83E-02 7.16E-02 6.52E-02 6.29E-02 6.53E-02 6.69E-02 Other wait Floatingpoint operation Other instruction commit Branch instruction Other wait Store port Instruction busy wait fetch wait Barrier synchronizati 8.53E-03 8.71E-03 7.35E-03 7.65E-03 6.74E-03 9.62E-03 9.94E-03 8.84E-03 5.36E-03 5.77E-03 5.93E-03 6.01E-03 7.54E-03 2.94E-01 2.83E-01 2.79E-01 2.76E-01 2.80E-01 2.75E-01 2.75E-01 2.75E-01 2.75E-01 2.79E-01 2.80E-01 2.81E-01 2.80E-01 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 1 instruction commit on wait wait wait 3.38E+00 3.28E+00 3.23E+00 3.15E+00 3.16E+00 3.16E+00 3.15E+00 3.16E+00 3.16E+00 3.14E+00 3.13E+00 3.14E+00 3.19E+00 3.23E-03 4.46E-03 3.71E-03 4.87E-03 5.58E-03 5.78E-03 5.72E-03 4.79E-03 2.12E-03 3.69E-03 4.10E-03 4.27E-03 4.36E-03 6.22E-05 1.68E-01 2.42E-01 4.28E-01 4.43E-01 4.28E-01 4.30E-01 4.18E-01 3.98E-01 4.34E-01 4.47E-01 4.35E-01 3.56E-01 2 instruction 3 instruction 4 instruction commit 6.91E-01 6.72E-01 6.58E-01 6.37E-01 6.43E-01 6.42E-01 6.42E-01 6.41E-01 6.36E-01 6.36E-01 6.37E-01 6.38E-01 6.48E-01 commit 2.47E-01 2.49E-01 2.51E-01 2.48E-01 2.48E-01 2.48E-01 2.49E-01 2.49E-01 2.51E-01 2.49E-01 2.49E-01 2.49E-01 2.49E-01 Statistics SFI(Store Cache L1D,L2 miss rate commit 1.58E-01 1.49E-01 1.45E-01 1.42E-01 1.44E-01 1.43E-01 1.41E-01 1.42E-01 1.40E-01 1.40E-01 1.39E-01 1.40E-01 1.44E-01 Other instruction Total commit 4.38E-01 4.26E-01 4.21E-01 4.10E-01 4.09E-01 4.08E-01 4.09E-01 4.09E-01 4.10E-01 4.10E-01 4.10E-01 4.09E-01 4.14E-01 0.00E+00 1.75E-04 4.90E-05 6.74E-04 0.00E+00 7.57E-05 0.00E+00 7.19E-06 0.00E+00 0.00E+00 0.00E+00 0.00E+00 8.17E-05 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 rate 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 100% 1.00 90% 0.90 80% 0.80 70% 0.70 60% 0.60 50% 0.50 vector Non- Floating- contiguous contiguous point structure scatter store register spill store instruction instruction store instruction 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 4.51E+07 5.41E+08 instruction 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% Other FLOPS hardware prefetch Process 4.93% 5.28% 5.95% 3.66% 3.84% 4.00% 3.59% 3.48% 3.71% 4.83% 3.71% 3.74% 4.23% Thread 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 7.0E+00 4 instruction commit 3 instruction commit 2 instruction commit 6.0E+00 1 instruction commit Barrier synchronization wait Instruction fetch wait 5.0E+00 Store port busy wait Other wait Branch instruction wait 4.0E+00 Floating-point operation wait Integer operation wait Floating-point load L1D cache access wait (*) 3.0E+00 rate (/Load- 40% 0.40 30% 0.30 20% 0.20 Floating-point load L2 cache access wait Integer load L1D cache access wait rate (/Load- store store instruction) instruction) 0.00174 0.00770 0.00462 0.00262 0.00262 0.00262 0.00262 0.00262 0.00262 0.00262 0.00263 0.00262 0.00314 10% 0% Scalar DCZVA prefetch prefetch instruction register spill store instruction instruction instruction point Floating- instruction FMA point except FMA instruction reciprocal and instruction reciprocal 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 2.99E+04 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.49E+03 2.48E+03 2.49E+03 2.49E+03 2.99E+04 2.83E+03 2.82E+03 2.82E+03 2.82E+03 2.82E+03 2.83E+03 2.83E+03 2.82E+03 2.82E+03 2.82E+03 2.83E+03 2.82E+03 3.39E+04 3.39E+04 1.55E+09 1.52E+09 1.51E+09 1.48E+09 1.48E+09 1.48E+09 1.48E+09 1.48E+09 1.49E+09 1.48E+09 1.48E+09 1.48E+09 1.79E+10 Single Half precision precision floating- floating- floating- Active point point point element rate operation operation operation 1.37.E+10 1.31.E+10 1.28.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.22.E+10 1.49.E+11 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 0.00.E+00 GFLOPS by Extra Process 2.04 1.97 1.94 1.88 1.88 1.88 1.88 1.88 1.87 1.87 1.87 1.87 22.82 Floatingpoint conversion instruction Floatingpoint move Integer Branch Predicate instruction instruction instruction 0 1 2 3 4 5 6 7 8 9 10 11 1 flow rate 2 flows rate (%) (%) (%) CMG 0 total 94.62% 95.94% 96.69% 98.00% 98.00% 98.00% 98.00% 98.00% 98.00% 98.00% 98.00% 98.00% 97.44% 100.00% graphic instruction 1.31E+08 1.23E+08 1.19E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.13E+08 1.39E+09 Other instruction (*)Include wait time for integer L1D cache access Total Power Consumption (W) Microoperation instruction Element 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 7.94E+09 7.75E+09 7.64E+09 7.46E+09 7.46E+09 7.46E+09 7.46E+09 7.46E+09 7.45E+09 7.44E+09 7.44E+09 7.44E+09 9.04E+10 9.04E+10 Register manipulated manipulated instruction Power consumption used by core Power Power consumption consumption used by L2 used by cache memory 1.40E+00 1.90E+00 instruction 8.75E+07 6.42E+08 8.01E+07 6.24E+08 7.71E+07 6.12E+08 6.97E+07 5.94E+08 6.93E+07 5.97E+08 6.92E+07 5.97E+08 6.92E+07 5.97E+08 7.02E+07 5.96E+08 7.27E+07 5.91E+08 7.03E+07 5.91E+08 6.95E+07 5.91E+08 7.01E+07 5.91E+08 8.75E+08 7.22E+09 8.10E+09 3.61E+08 3.29E+08 3.10E+08 2.80E+08 2.81E+08 2.81E+08 2.81E+08 2.80E+08 2.77E+08 2.79E+08 2.80E+08 2.79E+08 3.52E+09 3.52E+09 1.86E+08 1.82E+08 1.82E+08 1.78E+08 1.78E+08 1.78E+08 1.78E+08 1.79E+08 1.81E+08 1.79E+08 1.78E+08 1.78E+08 2.16E+09 2.16E+09 6.00E+07 5.85E+07 5.77E+07 5.64E+07 5.64E+07 5.64E+07 5.64E+07 5.64E+07 5.63E+07 5.63E+07 5.63E+07 5.63E+07 6.84E+08 6.84E+08 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 Instruction 0 flow rate 5.38% 4.06% 3.31% 2.00% 2.00% 2.00% 2.00% 2.00% 2.00% 2.00% 2.00% 2.00% 2.56% Crypto- Process 1.28E+09 1.23E+09 1.21E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.16E+09 1.42E+10 3.35E+10 instruction MOVPRFX instruction Math functional instruction Thread 0 0 0 0 0 0 0 0 0 0 0 0 Memory busy rate execution time Floating-point move and Gather instruction rate (%) Double precision L1 busy rate execution time L2 busy rate execution time 0 conversion instruction FloatingGathering Integer busy rate execution time Process demand rate(L1D,L2 miss) Floating-point instruction instruction Floating-point busy rate execution time hardware prefetch rate(L1D,L2 miss) Memory throughput peak ratio prefetch 0.0E+00 L2 miss software prefetch rate(L1D,L2 miss) (/Effective instruction) Floating-point operation peak ratio instruction 2.22E+08 2.22E+08 2.22E+08 2.22E+08 2.22E+08 2.22E+08 2.22E+08 2.22E+08 2.21E+08 2.21E+08 2.21E+08 2.21E+08 2.66E+09 ---------------------------------------L1D miss SIMD instruction ratio Prefetch port busy wait by software prefetch Prefetch port busy wait by hardware prefetch 0.00 CMG Contiguous 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 Integer load memory access wait 1.0E+00 0.10 Non-SIMD Predicate Integer load L2 cache access wait 2.0E+00 Floating-point load memory access wait 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 Non-SIMD contiguous Other instruction commit Cycle Accounting execution time(s) (/Load-store instruction) Fetch L1D TLB miss L2D TLB miss SIMD Single vector L1/L2 Injection mode allocate prefetch rate prefetch rate Non-SIMD instruction L2 Injection First-fault register fill prefetch rate 48.34% 48.92% 50.49% 51.69% 55.04% 57.20% 50.57% 49.56% 49.33% 49.16% 49.26% 50.23% 50.82% 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 Prefetch instruction Non-SIMD Stream mode Thread 0 0 0 0 0 0 0 0 0 0 0 0 instruction prefetch 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 Store instruction SIMD Multiple load Process software prefetch Interlock) Load-store instruction Load instruction Instruction busy wait by hardware Floating- point pipeline A operation pipeline A Thread 0 0 0 0 0 0 0 0 0 0 0 0 Memory access wait & Cache access wait busy wait by Thread 0 0 0 0 0 0 0 0 0 0 0 0 (*) Include wait time for integer L1D cache access Integer operation pipeline A L1D miss Load-store 1.06% 1.37E+10 1.31E+10 1.28E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.22E+10 1.49E+11 Prefetch port Prefetch port element rate instruction) 7.49E+09 7.30E+09 7.20E+09 7.03E+09 7.03E+09 7.03E+09 7.03E+09 7.03E+09 7.02E+09 7.01E+09 7.01E+09 7.01E+09 8.52E+10 Thread 9 Process Floatingoperation pipeline B busy rate 0.21 0.22 0.24 0.22 0.23 0.22 0.22 0.23 0.22 0.23 0.22 0.23 2.70 Thread 11 point operation pipeline A 3.26% 3.11% 3.03% 2.89% 2.89% 2.89% 2.89% 2.89% 2.89% 2.89% 2.89% 2.89% 2.95% Cycle Accounting GIPS Thread 8 Floating- Busy 2.29 2.19 2.13 2.03 2.03 2.03 2.03 2.03 2.03 2.03 2.03 2.03 24.88 IPC Thread 10 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 6.01E+00 Prefetch port busy wait point instruction point Thread 7 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total 512 2.196 Floating- Floating- Thread 0 0 0 0 0 0 0 0 0 0 0 0 Vector length (bit) CPU frequency (GHz) ComputeTemperature_SP_EB, 1 SIMD Memory throughput Thread 6 Process CMG 0 total -o 出⼒するCSVファイル名 Memory throughput Thread 5 time (s) point operation Thread 4 -Icpupa CPU内で起こる様々なイベントの測定結果を変換 0 Measured region GFLOPS Thread 3 -d 結果を⼊⼒するディレクトリ指定 0 CMG no. FloatingExecution Thread 2 Fri Dec 17 00:42:51 2021 fx43-s00-b01-05 Statistics Thread 1 Measured time Node name Thread 0 -A 測定時のおまじない ⼀つのコマンドで複数の役割があるため) 作成されたcsvと、システム上にある cpu_pa_report.xlsmをPCにコピーし、エクセル で開くと測定区間の詳細なデータが出る 4.21E+08 1.31E+08 4.20E+08 1.10E+08 4.19E+08 1.00E+08 4.18E+08 8.10E+07 4.18E+08 8.05E+07 4.18E+08 8.05E+07 4.18E+08 8.05E+07 4.18E+08 8.15E+07 4.17E+08 8.40E+07 4.17E+08 8.16E+07 4.17E+08 8.08E+07 4.17E+08 8.13E+07 5.01E+09 1.07E+09 6.09E+09 2.58E+08 2.50E+08 2.45E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.37E+08 2.88E+09 2.88E+09 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 Micro decompositio n instruction rate (%) 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% 99.99% Branch prediction miss rate 1.73E+09 1.72E+09 1.72E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 1.71E+09 2.06E+10 2.06E+10 7.49E+09 7.30E+09 7.20E+09 7.03E+09 7.03E+09 7.03E+09 7.03E+09 7.03E+09 7.02E+09 7.01E+09 7.01E+09 7.01E+09 8.52E+10 8.52E+10 Thread 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 CMG 0 total (W) 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 1.80E+00 2.16E+01 1.40E+00 1.90E+00 Power Consumption 3.0E+01 (%) 2.5E+01 0.15% 0.58% 0.45% 0.74% 0.97% 0.96% 0.95% 0.75% 0.09% 0.43% 0.50% 0.62% 0.60% 0.60% used by memory 2.0E+01 used by L2 cache used by core 1.5E+01 1.0E+01 5.0E+00 0.0E+00 1 CMG Destination (GB/s) Data Transfer CMGs CMG 0 total read write Own memory 1.78E+00 9.15E-01 Other memory 2.41E-02 3.65E-03 Tofu PCI 6.31E-06 5.54E-07 0.00E+00 0.00E+00 Copyright 2019 FUJITSU LIMITED 37

38.

プロファイラの使⽤ 5/5 スレッド並列化の⼿助けとなるプロファイラ情報 Other instruction commit Cycle Accounting execution time(s) 富岳・FX1000/700では CPU性能解析レポートが 利⽤可能 1.2E+01 4 instruction commit 3 instruction commit 2 instruction commit 1 instruction commit 1.0E+01 Barrier synchronization wait Instruction fetch wait Store port busy wait 8.0E+00 Effective instruction point operation Other wait バリア同期待ち Floating- Branch instruction wait Floating-point operation wait 6.0E+00 Integer operation wait Floating-point load L1D cache access wait (*) Floating-point load L2 cache access wait Integer load L1D cache access wait 4.0E+00 Integer load L2 cache access wait Floating-point load memory access wait Integer load memory access wait 2.0E+00 Prefetch port busy wait by software prefetch Prefetch port busy wait by hardware prefetch ---------------------------------------- Process 0 Thread 11 Thread 10 Thread 9 Thread 8 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Floating-point busy rate execution time Thread 2 0.0E+00 Thread 1 6.38E+10 7.55E+10 7.93E+10 3.81E+10 3.81E+10 3.81E+10 3.81E+10 6.80E+10 8.38E+10 3.79E+10 3.79E+10 3.98E+10 6.38E+11 Thread 0 1.24E+10 1.44E+10 1.50E+10 7.89E+09 7.89E+09 7.89E+09 7.89E+09 1.31E+10 1.58E+10 7.86E+09 7.86E+09 8.19E+09 1.26E+11 Integer busy rate execution time L1 busy rate execution time L2 busy rate execution time Memory busy rate execution time (*)Include wait time for integer L1D cache access 38

39.

コア内の並列性 演算命令とスケジューリング

40.

コア内の並列性 演算器A 演算器B Register Register Cache • 1スレッドが割り当てられたコアでは複 数の演算器があり,プロセス並列, スレッド並列と同様に,なるべく全て が遊ぶことなく働いてほしい • 演算・命令レベルでの並列性を考え ないといけない • ここでは以下を説明 • SIMD • ソフトウェアパイプラン 40

41.

演算・命令レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo このループの動きは 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 41

42.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo このループの動きは b(1)のロード 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 42

43.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo このループの動きは b(1)のロード c(1)のロード 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 43

44.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo このループの動きは b(1)のロード c(1)のロード 加算 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 44

45.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 45

46.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo 46

47.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア 47

48.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(4)へのストア 48

49.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(4)へのストア 同じ処理 49

50.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(5)へのストア 同じ処理 50

51.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(5)へのストア 同じ処理 51

52.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(4)へのストア 同じ処理 52

53.

演算レベルの並列性 do i=1, n a(i) = b(i) + c(i) enddo 少し分解して考える do i=1, n b(i)のロード c(i)のロード b(i)とc(i)を⾜す 結果をa(i)にストアする enddo このループの動きは b(1)のロード c(1)のロード 加算 a(1)へのストア b(2)のロード c(2)のロード 加算 a(2)へのストア b(3)のロード c(3)のロード 加算 a(3)へのストア b(4)のロード c(4)のロード 加算 a(4)へのストア ループの違う i に対して、同じ処 理を繰り返している 53

54.

SIMD こういった、同じ処理を複数のデータにやることを SIMD(single instruction multiple data) と呼ぶ. 演算器A 演算器B B1 B2 B3 B4 B5 B6 B7 B8 Register Register R1 R2 R3 R4 R5 R6 R7 R8 Cache コア内の演算機と,演算機にデータを与える/受け取るレジ スタには,SIMD対応になっているものがある 54

55.

SIMDとは 同じ処理を同時に幾つのデータに対して⾏えるか という数を SIMD幅(あるいはベクトル⻑)とい う 最近の計算機では、扱うデータによって異る SIMD幅を取れるものがある A64FX(富岳/FX1000/FX700)の例 Intel) SSE、AVX, AVX-512, VNNI AMD) SSE, AVX Arm/富⼠通) NEON, Scalable Vector Extension 現在は512bit(将来、例えば1024bitの機種が できても同じプログラムで1024bitにScalableに 対応) 55

56.

SIMD 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 3)SIMD化動作イメージ 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo do i=1, n, 4 b(i+{0,1,2,3})のロード c(i+{0,1,2,3})のロード 加算4つ 結果をa(i+{0,1,2,3})にストア enddo ※コンパイラが⾃動でやる 56

57.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo 57

58.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 命令1 b(i+0), b(i+1), b(i+2), b(i+3) のロード 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo 58

59.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo 命令1 b(i+0), b(i+1), b(i+2), b(i+3) のロード 命令2 c(i+0), c(i+1), c(i+2), c(i+3) のロード 59

60.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo 命令1 b(i+0), b(i+1), b(i+2), b(i+3) のロード 命令2 c(i+0), c(i+1), c(i+2), c(i+3) のロード 命令3 加算4つ 60

61.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = b(i) + c(i) enddo 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = b(i+0) + c(i+0) a(i+1) = b(i+1) + c(i+1) a(i+2) = b(i+2) + c(i+2) a(i+3) = b(i+3) + c(i+3) enddo 命令1 b(i+0), b(i+1), b(i+2), b(i+3) のロード 命令2 c(i+0), c(i+1), c(i+2), c(i+3) のロード 命令3 加算4つ 命令4 a(i+0), a(i+1), a(i+2), a(i+3) のストア 61

62.

SIMDとリカレンス 1)オリジナル do i=1, n a(i) = a(i-1) + c(i) enddo 2)SIMD化ソースのイメージ do i=1, n, 4 a(i+0) = a(i-1+0) + c(i+0) a(i+1) = a(i-1+1) + c(i+1) a(i+2) = a(i-1+2) + c(i+2) a(i+3) = a(i-1+3) + c(i+3) enddo 命令1 a(i-1+0), a(i-1+1), a(i-1+2), a(i-1+3) のロード 命令2 c(i+0), c(i+1), c(i+2), c(i+3) のロード 命令3 加算4つ 命令4 a(i+0), a(i+1), a(i+2), a(i+3) のストア 値が決まる前にロードしてしまい 結果が合わなくなるので、SIMDできない 62

63.

ソフトウェアパイプライン 現代のコンピュータは「⼀つの命令を1クロックサイクルで実⾏できる」と思われている. これは、正しくもあるし、間違いでもある コンピュータのCPUの中では、⼀つの命令はいくつかのステージに分解されて実⾏される 1命令 開始 Stage2 Stage1 Stage3 Stage4 終了 なので、実際には⼀つの命令が、「始まってからに着⽬すると1クロックでは実⾏できない FMA演算命令の平均的レイテンシ 富岳 京 FX100 Intel 9 6 6 5 単位 クロックサイクル 63

64.

ソフトウェアパイプライン 現代のコンピュータは「⼀つの命令を1クロックサイクルで実⾏できる」と思われている. これは、正しくもあるし、間違いでもある コンピュータのCPUの中では、⼀つの命令はいくつかのステージに分解されて実⾏される 1命令 開始 Stage2 Stage1 Stage3 Stage4 終了 なので、実際には⼀つの命令が、「始まってからに着⽬すると1クロックでは実⾏できない FMA演算命令の平均的レイテンシ 富岳 京 FX100 Intel 9 6 6 5 単位 クロックサイクル 64

65.

ソフトウェアパイプライン 現代のコンピュータは「⼀つの命令を1クロックサイクルで実⾏できる」と思われている. これは、正しくもあるし、間違いでもある コンピュータのCPUの中では、⼀つの命令はいくつかのステージに分解されて実⾏される 1命令 開始 Stage2 Stage1 Stage3 Stage4 終了 なので、実際には⼀つの命令が、「始まってからに着⽬すると1クロックでは実⾏できない FMA演算命令の平均的レイテンシ 富岳 京 FX100 Intel 9 6 6 5 単位 クロックサイクル 65

66.

ソフトウェアパイプライン 現代のコンピュータは「⼀つの命令を1クロックサイクルで実⾏できる」と思われている. これは、正しくもあるし、間違いでもある コンピュータのCPUの中では、⼀つの命令はいくつかのステージに分解されて実⾏される 1命令 開始 Stage2 Stage1 Stage3 Stage4 終了 なので、実際には⼀つの命令が、「始まってからに着⽬すると1クロックでは実⾏できない FMA演算命令の平均的レイテンシ 富岳 京 FX100 Intel 9 6 6 5 単位 クロックサイクル 66

67.

ソフトウェアパイプライン 現代のコンピュータは「⼀つの命令を1クロックサイクルで実⾏できる」と思われている. これは、正しくもあるし、間違いでもある コンピュータのCPUの中では、⼀つの命令はいくつかのステージに分解されて実⾏される これをパイプラインという 1命令 開始 Stage2 Stage1 Stage3 Stage4 終了 なので、実際には⼀つの命令が、「始まってからに着⽬すると1クロックでは実⾏できない FMA演算命令の平均的レイテンシ 富岳 京 FX100 Intel 9 6 6 5 単位 クロックサイクル 67

68.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 68

69.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 69

70.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 70

71.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 71

72.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 72

73.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 73

74.

ソフトウェアパイプライン ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる do i=1, n a(i) = b(i) + c(i) enddo 次のiへ このとき実⾏するハードウェアの想定 • Load命令は3サイクル • Add命令は3サイクル • Store命令は1サイクル • ロードパイプは2本(同時に⼆つのロード命令を実⾏) • ストアパイプは1本(同時に⼀つのストア命令を実⾏) • 同時命令実⾏数は4 b(i) c(i) load load wait wait wait wait クロック サイクル (時間) add wait wait store a(i) 4命令で7サイクルかかる 74

75.

ソフトウェアパイプライン do i=1, n a(i) = b(i) + c(i) enddo 次のiへ b(i) この状態だとループ i が完全に終わってから ループ i+1 を始めているが wait の時に i+1 のloadを始めればよいのでは︖ c(i) load load wait wait wait wait add クロック サイクル (時間) wait wait store a(i) 4命令で7サイクルかかる 75

76.

ソフトウェアパイプライン do i=1, n a(i) = b(i) + c(i) enddo b(i) Loadの後を 拡⼤ load wait wait add c(i) load 具体的にロードパイプの動きを⾒てみると、Stage1は空くので、次のループ 回転 i+1 のロードのStage1を始めて良い ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ wait wait 76

77.

ソフトウェアパイプライン do i=1, n a(i) = b(i) + c(i) enddo b(i) Loadの後を 拡⼤ load wait wait add c(i) load 具体的にロードパイプの動きを⾒てみると、Stage1は空くので、次のループ 回転 i+1 のロードのStage1を始めて良い ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ ロードパイプ1 Stage1 Stage2 Stage3 ・・・ ロードパイプ2 Stage1 Stage2 Stage3 ・・・ wait wait 77

78.

ソフトウェアパイプライン do i=1, n a(i) = b(i) + c(i) enddo 次のiへ b(i) ループ i の途中からループ i+1 を始めて、⼆ つのループを重ねて実⾏すれば、実⾏時間は 短くできるはず c(i) load load wait wait wait wait add クロック サイクル (時間) wait wait store a(i) 4命令で7サイクルかかる 78

79.

ソフトウェアパイプライン i それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア i 同時命令実⾏数は4 クロック サイクル (時間) 79

80.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア i i i+1 i+1 同時命令実⾏数は4 クロック サイクル (時間) 80

81.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア i i i+1 i+1 i+2 i+2 同時命令実⾏数は4 クロック サイクル (時間) 81

82.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア i i i+1 i+1 i+2 i+2 i+3 i+3 同時命令実⾏数は4 i ⾜し合わせるデータが揃った クロック サイクル (時間) 82

83.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 クロック サイクル (時間) 83

84.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 クロック サイクル (時間) 84

85.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i 書き込む値が 揃った 85

86.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 86

87.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 87

88.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i i回転⽬のロード Add i i回転⽬の加算 Store i i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 88

89.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i回転⽬のストア 89

90.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 90

91.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 i+6 91

92.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 i+6 i+7 92

93.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) 同時命令実⾏数は4 i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 この図だと iからi+8までの9回転分で15サイクル オリジナルだと9×7=63サイクル必要 i+6 i+7 i+8 93

94.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+7 i+7 i+4 i+1 i+8 i+8 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 ループが9回転以上する場合 カーネルという、CPUのスペック通 りに同時に4命令実⾏する部分 が動き続ける これで1クロックごとに結果が得ら れ、1クロックで1命令となる プロローグ i+6 カーネル エピローグ i+7 i+8 94

95.

ソフトウェアパイプライン それをするのを ソフトウェアパイプライン という Load i Add i Store i i回転⽬のロード i回転⽬の加算 i回転⽬のストア クロック サイクル (時間) i i i+1 i+1 i+2 i+2 i+3 i+3 i i+4 i+4 i+1 i+5 i+5 i+2 i+6 i+6 i+3 i i+4 i+1 i+5 i+2 i+6 i+3 ループが短い場合(この図では7 回転).4命令同時実⾏してい る時間がほぼない ↓ 短いとソフトウェアパイプラインは 効果がうすい i+4 wait i+5 i+6 95

96.

ソフトウェアパイプライン リカレンスがあるとソフトウェアパイプライン できない do i=1, n a(i) = a(i-1) + b(i) enddo a(i)をストアする前に a(i)をロードしてしまう ので計算結果が 狂ってしまう bのロード aのロード i i-1 i+1 i i+2 i+1 i+3 i+2 i i+4 i+3 i+1 i+5 i+4 i+2 aのストア i+6 i+5 i+3 i i+7 i+6 i+4 i+1 i+8 i+7 i+5 i+2 i+6 i+3 i+7 i+4 i+8 wait i+5 i+6 i+7 i+8 96

97.

マシンのGFLOPSの算出 Clock Freq. 2.2 GHz Core GFLOPS 70 GFLOPS L1D Cache 64 KiB (256GB /s) CMG CPU # of Core 12 GFLOPS 884 GFLOPS Memory 8 GiB (256 GB/s) L2 Cache 8 Mib (1024 GB/s) # of CMG 4 GFLOPS 3379 GFLOPS Memory 32 GiB Node # of CPU 1 # of Node Syste GFLOPS m Memory 5760 1コア当たりの演算性能 クロック 2.2GHz x A=BxC+Dのような計算を1命令で実 FMA 2 ⾏する Fused Multiply Add x SIMD 8 x PIPE 2 = 70.4GFLOPS 同時に実⾏できる命令数 19.4 PFLOPS 180 TiB 97

98.

マシンのGFLOPSの算出 Clock Freq. 2.2 GHz Core GFLOPS 70 GFLOPS L1D Cache 64 KiB (256GB /s) CMG CPU # of Core 12 GFLOPS 884 GFLOPS Memory 8 GiB (256 GB/s) L2 Cache 8 Mib (1024 GB/s) # of CMG 4 GFLOPS 3379 GFLOPS Memory 32 GiB Node # of CPU 1 # of Node Syste GFLOPS m Memory 5760 19.4 PFLOPS 180 TiB 1コア当たりの演算性能 クロック 2.2GHz x FMA 2 x SIMD 8 SIMDで実⾏しないと ×8から×1になってしまう x PIPE 2 = 70.4GFLOPS 同時に実⾏できる命令数 Machine 京 SIMD width 2 (128 bit) # of register 256 FX100 FX1000 4 (256 bit) 8 (512 bit) 256 32 SIMDありきの性能なのに注意 98

99.

マシンのGFLOPSの算出 Clock Freq. 2.2 GHz Core GFLOPS 70 GFLOPS L1D Cache 64 KiB (256GB /s) CMG CPU # of Core 12 GFLOPS 884 GFLOPS Memory 8 GiB (256 GB/s) L2 Cache 8 Mib (1024 GB/s) # of CMG 4 GFLOPS 3379 GFLOPS Memory 32 GiB Node # of CPU 1 # of Node Syste GFLOPS m Memory 5760 19.4 PFLOPS 180 TiB 1コア当たりの演算性能 クロック 2.2GHz ソフトウェアパイプラインができないと1ク ロックで1命令実⾏していると⾒なせない x FMA 2 x SIMD 8 x PIPE 2 = 70.4GFLOPS 同時に実⾏できる命令数 Machine 京 SIMD width 2 (128 bit) # of register 256 FX100 FX1000 4 (256 bit) 8 (512 bit) 256 32 SIMDありきの性能なのに注意 99

100.

メモリ・キャッシュ・レジスタ間のデータ転送

101.

メモリの階層構造 メモリ(記憶装置)はコンピュータの中では階層構造をしてゆき, 上にあるものほど⾼速だが記憶容量が少ない (図中⾊が付いているのが記憶装置) Core Core Core Core 演算器 演算器 Register Register コア固有のCache 共有 Cache Memory 101

102.

メモリの階層構造 よくあるイメージ 図書館 本棚 机に置いてある本 今作業中のノート 数万冊 数百冊 いいとこ10冊くらい? 1冊 アクセス 低速 速度 高速 容量 小 大 102

103.

メモリの階層構造 パソコンだと HDDやSSD 1TB HDD/SSD メモリ 16GB メモリ キャッシュメモリ L3 12MB L2 256KB/core L3 64KB/core レジスタ 変数1個分 レジスタ が複数 アクセス 低速 速度 高速 容量 小 大 103

104.

メモリの階層構造 パソコンだと HDDやSSD 1TB HDD/SSD メモリ 16GB メモリ キャッシュメモリ L3 12MB キャッシュメモリ L2 256KB/core L3 64KB/core アクセス 低速 速度 容量 大 レジスタ 変数1個分 レジスタ が複数 高速 メモリと違って小容量 独自の凝った仕組みがありと それゆえに起きる問題をご紹介 小 104

105.

メモリとキャッシュ キャッシュメモリは,メモリの⼀部のデータを選択的に保持している より⾼速な記憶領域 「選択的に」というのはどうしているのか︖ メモリは1バイトごとにアドレスがあり管理されている 0 1 ・・・ 126 128Byte 127 128 129 ・・・ 254 128Byte 255 256 257 ・・・ 382 128Byte 383 384 385 1バイト ・・・ 510 128Byte 511 512 513 ・・・ 128Byte キャッシュの仕組みでは,アドレスをNバイト(ここでは128バイト)ごとの単 位でまとめて,それぞれをキャッシュに置くか置かないかを管理している 105

106.

キャッシュの構造とラインアクセス どうやって管理しているのか )*+ ! " #$%&! #$%&" #$%&' ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ ,,, ,,, ,,, #$%&"'( ・・・ ・・・ CPU 演算機と レジスタ Cache 128Byte Memory この一枠(ライン)に128Byteの 塊で入る 1ライン128Byte,2 Way-set Associativeで 128ラインであり合計32KBのキャッシュの例 106

107.

キャッシュの構造とラインアクセス キャッシュの動作 Hitの場合 )*+ ! " ・・・ ・・・ ・・・ ・・・ 386 13186 ,,, ,,, ,,, #$%&"'( ・・・ ・・・ •L #$%&! #$%&" #$%&' 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に 変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. Line2のWay0かWay1に要求アドレスに 対応する128Byteのデータが入っていたらHit 107

108.

キャッシュの構造とラインアクセス キャッシュの動作 Hitの場合 )*+ ! " ・・・ ・・・ ・・・ ・・・ 386 13186 ,,, ,,, ,,, #$%&"'( ・・・ ・・・ •L #$%&! #$%&" #$%&' 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に 変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. Line2のWay0かWay1に要求アドレスに 対応する128Byteのデータが入っていたらHit 108

109.

キャッシュの構造とラインアクセス キャッシュの動作 Hitの場合 )*+ ! " ・・・ ・・・ ・・・ ・・・ 386 13186 ,,, ,,, ,,, #$%&"'( ・・・ ・・・ •L #$%&! #$%&" #$%&' 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に 変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. Line2のWay0かWay1に要求アドレスに 対応する128Byteのデータが入っていたらHit 109

110.

キャッシュの構造とラインアクセス キャッシュの動作 Hitの場合 )*+ •L #$%&! #$%&" #$%&' ,,, #$%&"'( ! " ・・・ ・・・ ・・・ ・・・ 386 13186 ,,, Hit ,,, ・・・ ・・・ 各ラインにはタグという,自分が「どの128Byte」を納め ているか情報を持っている 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に 変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. Line2のWay0かWay1に要求アドレスに 対応する128Byteのデータが入っていたらHit 110

111.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合① )*+ ! " #$%&! #$%&" #$%&' ・・・ ・・・ ・・・ ・・・ ,,, ,,, #$%&"'( 13186 ・・・ ,,, ・・・ 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 111

112.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合① )*+ ! " #$%&! #$%&" #$%&' ・・・ ・・・ ・・・ ・・・ ,,, ,,, #$%&"'( 13186 ・・・ ,,, ・・・ 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 112

113.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合① )*+ ! " #$%&! #$%&" #$%&' ・・・ ・・・ ・・・ ・・・ 386 13186 ,,, ,,, ,,, #$%&"'( ・・・ ・・・ 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 113

114.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② )*+ ! " ・・・ ・・・ #$%&! #$%&" #$%&' ・・・ ・・・ 642 13186 ,,, ,,, ,,, #$%&"'( ・・・ ・・・ 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 114

115.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② )*+ ! " ・・・ ・・・ #$%&! #$%&" #$%&' ・・・ ・・・ 642 13186 ,,, ,,, #$%&"'( ・・・ ただし今,ライン2には 先客がいて空きがないので 先客にどいてもらいたい 386 ,,, ・・・ 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 115

116.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② )*+ #$%&! #$%&" #$%&' ! " ・・・ ・・・ ・・・ ・・・ 642 13186 こっちは最近使っていな ,,, #$%&"'( ,,, ・・・ ,,, ・・・ タグには,同じラインの中で「最近使われたか」「最近 は使われていないか」を識別するための情報がある 最近使ってない方は,もういらないのでは? 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 116

117.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② )*+ ! " ・・・ ・・・ ・・・ ・・・ 642 386 ,,, ,,, ,,, #$%&"'( ・・・ 13186をどかして,386を代わりに入 れる ・・・ 6 18 13 #$%&! #$%&" #$%&' 1. アドレス49500の値を要求 2. 要求アドレスを128B単位のブロック番号に変換 ADDR=49500 ↓ INDEX=[ADDR/128]=386 49500の内容を含むブロックは386と判明 3. インデックスをライン番号に変換 LINE=MOD(INDEX,128)=2 4. 入っていなければ次のレベル(L2やメモリ)から データを持ってくる 117

118.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② どれをどかすか︖ どかすやりかた(=ラインの入れ替え方式)には種類がある • ラウンドロビン 今着目しているラインでは,さっきはWay0の中身をどかしたので,今度はWay1の中身を どかそう • ランダム 呼んで字のごとく • LRU★ • Least Recently Used の略 • さっき使ったばかりのデータは,また,すぐに使いそうだからとっておこう • その逆に,しばらく使っていないデータは,もう使わないだろう • 今着目しているLine中で,一番過去にアクセスされたWayの中身をどかす 118

119.

キャッシュの構造とラインアクセス キャッシュの動作 Missの場合② データ更新⽅式 CPUでデータを書き換えたら(ストア命令発生),そのデータはメモリに戻さないといけないが,いつそれ をやる? • ライトスルー方式 • ストア命令で,まずはキャッシュ中にあるデータが書き換えられる • このタイミングでメモリ上の対応する部分も書き換える • L2もライトスルー方式なら,メモリも書き換える • ライトバック方式 • キャッシュ中のデータを書き換えたか否かのフラグ(dirty flag)がある • そのデータがキャッシュからどかされるときに,dirty flagが立っていればメモリ上の対応する部分 を書き換える • 2ページ前でどかされたブロック番号13186のdirty flagが立っていれば,メモリ上の対応する部分 を書き換える 119

120.

キャッシュの構造とラインアクセス キャッシュスラッシング キャッシュの同じラインへのデータの出し入れが頻発することを Thrashingという ソース real(8) :: A(131072) real(8) :: B(131072) real(8) :: C(130172) DO i=1, 131072 tmp1=A(i) tmp2=B(i) tmp3=C(i) ・・・ ENDDO メモリ配置 A(1) ↓ B(1) ↓ ↑ A(131072) C(1) ↓ ↑ B(131072) ↑ C(131072) 先頭アドレス LOC( A ) = 1048576 LOC( B ) = 2097152 LOC( C ) = 3145728 この例でループ変数iを追っかけてみよう 120

121.

キャッシュの構造とラインアクセス ループがi=1のとき 配列 A(1) B(1) C(1) 128B単位の アドレス ブロック番号 ライン番号 1048576 8192 0 2097152 16384 0 3145728 24576 0 )*+ ! レジスタ A(1) B(1) C(1) DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO " #$%&! #$%&" #$%&' 8192 ,,, ,,, Miss ,,, #$%&"'( 121

122.

キャッシュの構造とラインアクセス ループがi=1のとき 配列 A(1) B(1) C(1) 128B単位の アドレス ブロック番号 ライン番号 1048576 8192 0 2097152 16384 0 3145728 24576 0 レジスタ A(1) B(1) C(1) )*+ ! " #$%&! #$%&" #$%&' 8192 16384 ,,, ,,, DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO Miss ,,, #$%&"'( 122

123.

キャッシュの構造とラインアクセス ループがi=1のとき 配列 A(1) B(1) C(1) 128B単位の アドレス ブロック番号 ライン番号 1048576 8192 0 2097152 16384 0 3145728 24576 0 )*+ 92 ! " #$%&! #$%&" #$%&' 24576 16384 ,,, ,,, 81 レジスタ A(1) B(1) C(1) DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO Miss ,,, #$%&"'( 123

124.

キャッシュの構造とラインアクセス ループがi=2のとき 配列 A(2) B(2) C(2) 128B単位の アドレス ブロック番号 ライン番号 1048584 8192 0 2097160 16384 0 3145736 24576 0 レジスタ A(2) B(2) C(2) )*+ ! " #$%&! #$%&" #$%&' 24576 8192 ,,, ,,, 16 38 DO i=1, 131072 tmp1=A(2) tmp2=B(2) tmp3=C(2) ・・・ ENDDO 4 Miss ,,, #$%&"'( 124

125.

キャッシュの構造とラインアクセス ループがi=2のとき 配列 A(2) B(2) C(2) 128B単位の アドレス ブロック番号 ライン番号 1048584 8192 0 2097160 16384 0 3145736 24576 0 5 24 76 )*+ ! " #$%&! #$%&" #$%&' 16384 8192 ,,, ,,, レジスタ A(2) B(2) C(2) DO i=1, 131072 tmp1=A(2) tmp2=B(2) tmp3=C(2) ・・・ ENDDO Miss ,,, #$%&"'( 125

126.

キャッシュの構造とラインアクセス ループがi=2のとき 配列 A(2) B(2) C(2) 128B単位の アドレス ブロック番号 ライン番号 1048584 8192 0 2097160 16384 0 3145736 24576 0 レジスタ A(2) B(2) C(2) )*+ ! " #$%&! #$%&" #$%&' 16384 24576 ,,, ,,, Miss 81 DO i=1, 131072 tmp1=A(2) tmp2=B(2) tmp3=C(2) ・・・ ENDDO 92 同じラインの⼊れ替えがひたすら発⽣ AとCはアクセスするたびにキャッシュミス ,,, #$%&"'( 126

127.

キャッシュの構造とラインアクセス キャッシュスラッシング回避 配列の先頭アドレスをずらそう ここでは,Cだけ128バイト(1ライン分)ずらしてみる ソース real(8) :: A(131072) real(8) :: B(131072+16) real(8) :: C(130172) メモリ配置 A(1) DO i=1, 131072 tmp1=A(i) tmp2=B(i) tmp3=C(i) ・・・ ENDDO 先頭アドレス LOC( A ) = 1048576 LOC( B ) = 2097152 LOC( C ) = 3145856 (以前は3145728) ↓ B(1) C(1) ↓ ↑ A(131072) ・・ ↓ ↑ B(131072) ↑ C(131072) この例でループ変数iを追っかけてみよう 127

128.

キャッシュの構造とラインアクセス ループがi=1のとき 配列 A(1) B(1) C(1) 128B単位の アドレス ブロック番号 ライン番号 1048576 8192 0 2097152 16384 0 3145856 24577 0 レジスタ A(1) B(1) C(1) )*+ ! " #$%&! #$%&" #$%&' 8192 16384 ,,, ,,, Miss DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO Miss ,,, #$%&"'( 128

129.

キャッシュの構造とラインアクセス ループがi=1のとき 配列 A(1) B(1) C(1) 128B単位の アドレス ブロック番号 ライン番号 1048576 8192 0 2097152 16384 0 3145856 24577 1 )*+ ! " 8192 16384 #$%&! #$%&" #$%&' 24577 ,,, ,,, レジスタ A(1) B(1) C(1) DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO Miss ,,, #$%&"'( 129

130.

キャッシュの構造とラインアクセス ループがi=2のとき 配列 A(2) B(2) C(2) 128B単位の アドレス ブロック番号 ライン番号 1048584 8192 0 2097160 16384 0 3145864 24577 1 レジスタ A(1) B(1) C(1) )*+ Hit ! " 8192 16384 #$%&! #$%&" #$%&' 24577 ,,, ,,, Hit Hit DO i=1, 131072 tmp1=A(1) tmp2=B(1) tmp3=C(1) ・・・ ENDDO 以降i=17までキャッシュミスなし ,,, #$%&"'( 130

131.

キャッシュの構造とラインアクセス False Sharing 複数のコアが共有しているラインで、誰かが書き換えを行ったときに起きる現象 コア1 コア2 演算機とレジスタ A B C D キャッシュ 演算機とレジスタ A B C D 128バイトのブロック A B C D は,コア1と2が両方キャッシュに コピーを持っている A B C D メモリ あるいはコア間共有キャッシュ 131

132.

キャッシュの構造とラインアクセス False Sharing 複数のコアが共有しているラインで、誰かが書き換えを行ったときに起きる現象 コア1 コア2 演算機とレジスタ キャッシュ 演算機とレジスタ 更新 無効 E B C D A B C D コア1がラインの内容を書き換えると コア1では当該ラインに更新フラグが その他コアでは当該ラインに無効フラグが つく A B C D メモリ あるいはコア間共有キャッシュ 132

133.

キャッシュの構造とラインアクセス False Sharing 複数のコアが共有しているラインで、誰かが書き換えを行ったときに起きる現象 コア1 コア2 演算機とレジスタ E B C D キャッシュ 演算機とレジスタ コア2がラインのBを参照するとき Bが入っているラインは無効フラグになっており値が変 わっていることを検知 A B C D A B C D メモリ あるいはコア間共有キャッシュ 133

134.

キャッシュの構造とラインアクセス False Sharing 複数のコアが共有しているラインで、誰かが書き換えを行ったときに起きる現象 コア1 コア2 演算機とレジスタ E B C D キャッシュ 演算機とレジスタ コア2がラインのBを参照するとき Bが入っているラインは無効フラグになっており値が変 わっていることを検知 A B C D キャッシュデータの整合性を保つため,コア1のキャッシュ からラインをメモリに書き戻し E B C D メモリ あるいはコア間共有キャッシュ 134

135.

キャッシュの構造とラインアクセス False Sharing 複数のコアが共有しているラインで、誰かが書き換えを行ったときに起きる現象 コア1 コア2 演算機とレジスタ E B C D キャッシュ 演算機とレジスタ コア2がラインのBを参照するとき Bが入っているラインは無効フラグになっており値が変 わっていることを検知 E B C D キャッシュデータの整合性を保つため,コア1のキャッシュ からラインをメモリに書き戻し E B C D メモリ あるいはコア間共有キャッシュ 135

136.

ストリームの考え⽅ do I=i, N A(i) = alpha * B(i) + C(i) enddo Register/演算器 A(i) = αB(i) + C(i) よくある計算ループ Aには⼀⽅的に書き込まれるだけ Memory Cache cache line A cache line B cache line C 136

137.

ストリームの考え⽅ do I=i, N A(i) = alpha * B(i) + C(i) enddo Register/演算器 よくある計算ループ Aには⼀⽅的に書き込まれるだけ Memory Cache cache line A(i) = αB(i) + C(i) cache line cache line ① A B C 137

138.

ストリームの考え⽅ do I=i, N A(i) = alpha * B(i) + C(i) enddo Register/演算器 A(i) = αB(i) + C(i) よくある計算ループ Aには⼀⽅的に書き込まれるだけ Memory Cache cache line A cache line B cache line C ② 138

139.

ストリームの考え⽅ do I=i, N A(i) = alpha * B(i) + C(i) enddo Register/演算器 ③ Memory 暗黙のロード Cache 演算結果 A(i) = αB(i) + C(i) よくある計算ループ Aには⼀⽅的に書き込まれるだけ A cache line cache line cache line ④ B C 139

140.

ストリームの考え⽅ do I=i, N A(i) = alpha * B(i) + C(i) enddo よくある計算ループ Aには⼀⽅的に書き込まれるだけ メモリとのやり取り(矢印)が4本4ストリームという Register/演算器 演算結果 A(i) = αB(i) + C(i) Memory Cache cache line ③ 暗黙のロード ④ ① B cache line ② C cache line A 140

141.

Z-Fill do I=i, N A(i) = alpha * B(i) + C(i) enddo よくある計算ループ Aには⼀⽅的に書き込まれるだけ 一方的に書き込むAは一旦キャッシュに持って来なくてもよいのでは? A64FXではZ-fillという機能がある (コンパイルオプション-Kzfill) キャッシュライン 確保命令 Register/演算器 Memory Cache 演算結果 A(i) = αB(i) + C(i) DCZVA ARMv8の命令セットが持つ命令.L2キャッシュに対して, 指定したアドレスに対応するキャッシュラインを作り0埋めする cache line ③ A cache line ① B cache line ② C 3ストリーム 141

142.

Z-Fill zfillあり -Kzfill キャッシュライン確保命令 Register/演算器 ←DCZVA命令というものが実体 Memory Cache cache line A(i) = αB(i) + C(i) cache line cache line ① 3stream A ② B ③ C 演算結果 zfillなし DCZVA instruction zfillあり DCZVA instruction 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 8.00E+00 2.73E+07 9.60E+01 3.28E+08 9.60E+01 3.28E+08 DCZVA) ARMv8の命令セットが持つ命令 L2キャッシュに対して,指定したアドレ スに対応するキャッシュラインを作り0埋 めする 142

143.

ストリームの考え⽅ do I=i, N A(i) = A(i) + B(i) * C(i) enddo Register/演算器 Memory Cache 演算結果 A(i) = αB(i) + C(i) Aは書き込みだけでなく 参照もされている場合 cache line ③ ロード ④ ① B cache line ② C cache line A これは当然 4ストリーム必要 143

144.

ストリームの考え⽅ do I=i, N A(i) = A(i) + D(1,i) * D(2,i) B(i) enddo C(i) Register/演算器 1 1 2 2 3 3 4 4 5 5 6 Memory Cache 演算結果 A(i) = αB(i) + C(i) D B C B C B C B C B C B ・・・ cache line B n Cn B m Cm ② ロード ③ ① A B n Cn B m Cm こうすると 3ストリームになる 144

145.

プリフェッチ • ソフトウェアパイプラインはロード3に3サイクルかかるという例で解説 • 実際には,データがキャッシュになく,データをメモリまで取りにゆくと,メモリ待ちとなり,より時 間がかかる コア/CPU b(i) 演算器 演算器 Register 次のiへ Register CacheCache c(i) load load wait wait wait wait add ・・・ wait クロック サイクル (時間) wait Memory store a(i) 145

146.

プリフェッチ • あらかじめ使うと分かっているデータは,ロード命令に先⽴ってメモリからキャッシュに持ってきてお けばメモリ待ち時間はなくなり,アクセス⾼速化→ プリフェッチ コア/CPU 演算器 演算器 Register Register CacheCache Memory • ハードウェアプリフェッチ • CPUの中の専⽤の回路が,今までのアクセス パターンから,次にアクセスするであろうメモリ 領域を予測し,キャッシュに持ってくる • ある程度簡単なアクセスパターン • 専⽤の回路は少ない • ソフトウェアプリフェッチ • コンパイラがプログラムを解析,プリフェッチ命 令をプログラム中に埋め込む • ある程度柔軟なアクセスパターン • プリフェッチ命令を⼊れただけできる 146

147.

プリフェッチ A64FX(富岳, FX1000, FX700)でのソフトウェアプリフェッチの利⽤ Cycle Accounting execution time(s) HWPF L1D miss demand rate (%) (/L1D miss) L1D miss hardware prefetch rate (%) (/L1D miss) L1D miss software prefetch rate (%) (/L1D miss) L2 miss rate (/Load-store instruction) L2 miss demand rate (%) (/L2 miss) L2 miss hardware prefetch rate (%) (/L2 miss) L2 miss software prefetch rate (%) (/L2 miss) 67.53% 3 instruction commit 67.56% 2 instruction commit 66.99% 4.41% 2.0E+01 L1キャッシュアクセス待ち 1 instruction commit Barrier synchronization wait 33.00% 32.99% 1.5E+01 0.01% Instruction fetch wait L2キャッシュアクセス待ち Store port busy wait 62.60% Other wait Branch instruction wait 67.91% 67.98% 44.07% 0.61% 59.85% 33.50% 0.00% 65.89% 1.0E+01 Floating-point operation wait Integer operation wait メモリアクセス待ち Floating-point load L1D cache access wait (*) 5.0E+00 Floating-point load L2 cache access wait Integer load L1D cache access wait Floating-point load memory access wait 0.0E+00 ハードウェア プリフェッチ 2 instruction) 4 instruction commit 1 L1D miss rate (/Load-store Other instruction commit 2.5E+01 SWPF ソフトウェア プリフェッチ Integer load memory access wait Prefetch port busy wait by software prefetch Prefetch port busy wait by hardware prefetch (*)Include wait time for integer L1D cache access 147

148.

まとめ • 単体性能最適化にまつわる、重要な概念・CPU内部で起きていることについて 紹介しました • CPUの性能を発揮するには、スレッド並列・SIMD・ソフトウェアパイプラインを適 応することが必須で、それには、プロセス並列(MPI並列)と同様に、1プロセスの 中でも、さまざまなレベルでの並列性を考慮する必要 • ロード・ストアを効率よく⾏うことも必要であり.キャッシュの動作を把握しておくこ とが必要 • 次回は単体性能最適化のさまざまな実例を紹介します 148