---
title: 第4回 配信講義　計算科学技術特論B （2024）
tags:  #計算科学 #cpu単体 #並列処理  
author: [R-CCS　計算科学研究推進室](https://convert.docswell.com/user/2300203199)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/37KD9WMPED.jpg?width=480
description: -------------------------------------------------------------- 第4回 5月9日 アプリケーションの性能最適化２ (CPU単体性能最適化) --------------------------------------------------------------- 第4回は，「CPU単体性能」についての第3回での講義内容をふまえ、「CPU単体性能」を出すために留意しておくべき事項。ノード内・CPU内・コア内の並列処理並びにメモリアクセスについて紹介する。
published: May 02, 24
canonical: https://convert.docswell.com/s/2300203199/KYW2VN-2024-05-02-143217
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/37KD9WMPED.jpg)

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


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LJ3RW1Y4E5.jpg)

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


# Page. 3

![Page Image](https://bcdn.docswell.com/page/8JDYKX55JG.jpg)

並列性能と、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


# Page. 4

![Page Image](https://bcdn.docswell.com/page/VEP6KPGD78.jpg)

並列処理の様々なレベル


# Page. 5

![Page Image](https://bcdn.docswell.com/page/27V3V26GJQ.jpg)

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


# Page. 6

![Page Image](https://bcdn.docswell.com/page/5JG3LR2DEL.jpg)

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


# Page. 7

![Page Image](https://bcdn.docswell.com/page/47Q5YVPXEP.jpg)

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


# Page. 8

![Page Image](https://bcdn.docswell.com/page/KE49WMY2J1.jpg)

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


# Page. 9

![Page Image](https://bcdn.docswell.com/page/L71KY86KEG.jpg)

スレッド並列


# Page. 10

![Page Image](https://bcdn.docswell.com/page/G7WDGZWPE2.jpg)

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


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4JZGL15673.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 12

![Page Image](https://bcdn.docswell.com/page/YE6YWL9LJV.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GE5GM1NME4.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 14

![Page Image](https://bcdn.docswell.com/page/972Y915R7R.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 15

![Page Image](https://bcdn.docswell.com/page/DJYG4ZK5JM.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 16

![Page Image](https://bcdn.docswell.com/page/V7NGY3R4E8.jpg)

リカレンス（データの依存性）
ある有限要素法の流体解析プログラム 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


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YJ9WP9M4J3.jpg)

リカレンス（データの依存性）
このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を
掛け合わせた値を、頂点に対応する節点に⾜し込む
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


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GJ8ND9LVED.jpg)

リカレンス（データの依存性）
このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を
掛け合わせた値を、頂点に対応する節点に⾜し込む
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


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LJLPMWLRER.jpg)

リカレンス（データの依存性）
このループは要素を順番に回って、要素の値と、要素の各頂点がもつ係数を
掛け合わせた値を、頂点に対応する節点に⾜し込む
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


# Page. 20

![Page Image](https://bcdn.docswell.com/page/47M4Y9MPEW.jpg)

リカレンス（データの依存性）
このループをスレッド並列すると、複数の要素を同時に処理することになるが
そうすると、リカレンスが⽣じるためできない
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


# Page. 21

![Page Image](https://bcdn.docswell.com/page/P7RW9GVYE9.jpg)

スレッド並列のためのリカレンス除去
カラーリングを導⼊して、要素を互いに隣り合っていないカラー（グループ）に分ける
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


# Page. 22

![Page Image](https://bcdn.docswell.com/page/PJXPQXZ4EX.jpg)

スレッド並列のためのリカレンス除去
メモリ上ではカラー毎に連続になるよう必要に応じて要素番号を付け替える
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


# Page. 23

![Page Image](https://bcdn.docswell.com/page/3JKD9W8P7D.jpg)

リカレンス（データの依存性）
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


# Page. 24

![Page Image](https://bcdn.docswell.com/page/LE3RW12475.jpg)

スレッド並列の実⾏形態
富岳，あるいは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


# Page. 25

![Page Image](https://bcdn.docswell.com/page/8EDYKXZ5EG.jpg)

スレッド並列の実⾏形態
富岳，あるいは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


# Page. 26

![Page Image](https://bcdn.docswell.com/page/V7P6KPDDJ8.jpg)

スレッド並列の実⾏形態
富岳，あるいは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


# Page. 27

![Page Image](https://bcdn.docswell.com/page/2JV3V21GEQ.jpg)

スレッド並列の実⾏形態
富岳，あるいは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


# Page. 28

![Page Image](https://bcdn.docswell.com/page/5EG3LR8D7L.jpg)

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


# Page. 29

![Page Image](https://bcdn.docswell.com/page/4JQ5YV9X7P.jpg)

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


# Page. 30

![Page Image](https://bcdn.docswell.com/page/K749WMX2E1.jpg)

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


# Page. 31

![Page Image](https://bcdn.docswell.com/page/LJ1KY8NK7G.jpg)

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


# Page. 32

![Page Image](https://bcdn.docswell.com/page/GJWDGZ4P72.jpg)

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


# Page. 33

![Page Image](https://bcdn.docswell.com/page/4EZGL126J3.jpg)

推奨されるスレッド並列の実⾏形態
推奨の実⾏形態
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


# Page. 34

![Page Image](https://bcdn.docswell.com/page/Y76YWLVLEV.jpg)

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


# Page. 35

![Page Image](https://bcdn.docswell.com/page/G75GM1DM74.jpg)

プロファイラの使⽤ 2/5
京/FX10/FX100でも使えたが、A64FX(富岳,FX1000/FX700)ではFAPPというプロファイラが
使える
ソース中で、測定したい部分をサブルーチン・関数fapp_start/fapp_stopで挟み実⾏ファイルを、
プロファイラの実⾏コマンドから実⾏．実⾏後できたデータを変換してエクセルで読む．
ソース例 (C/C++)
fapp_start(&quot;range&quot;, 1, 0);
for(i=0; i&lt;N+1; i++){
・・・
fapp_start(&quot;range&quot;, 2, 1);
for(j=0; j&lt;M+1; j++){
・・・
}
fapp_stop(&quot;range&quot;, 2, 1);
}
fapp_stop(&quot;range&quot;, 1, 0);
区間名
区間番号
レベル値
コンパイル例 (C/C++)
fccpx source.cpp –Nfjprof –o a.out
プロファイラ⽤のライブラリをリンクする指⽰
ただし指定しなくても、デフォルトで有効になっているので実
際には気にしなくて良い
-Nnofjprofならリンクしない
※clangモードの場合は-ffj-fjprof あるいは
–fj-no-fjprof
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/9J2Y918RJR.jpg)

プロファイラの使⽤ 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(&quot;range&quot;, 1, 0)
do i=0, N
・・・
call fapp_stop(&quot;range&quot;, 2, 1)
do j=0, M
・・・
enddo
call fapp_start(&quot;range&quot;, 2, 1)
enddo
call fapp_stop(&quot;range&quot;, 1, 0)
-C 測定時のおまじない
⼀つのコマンドで複数の役割があるため)
-Hevent=pa1〜17
測定するデータの種類を指定
-d
結果を出⼒するディレクトリ指定(-Heventの指定と合わせる)
-Icpupa
CPU内で起こる様々なイベントを測定する
-L 0
測定のレベル指定
ソース中の、fapp_start/fapp_stop関数・サブルーチンで指定した
レベル値が、ここでの指定値以下 (≦) のものを測定する
-LNだとソース中のレベル指定の値が ≦ N で
ある区間を測定する
-L0だと⾚字の区間だけを測定
-L1だと⾚字と⻘字の区間を測定
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/DEYG4Z65EM.jpg)

プロファイラの使⽤ 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 &amp; 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


# Page. 38

![Page Image](https://bcdn.docswell.com/page/VJNGY3Z478.jpg)

プロファイラの使⽤ 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


# Page. 39

![Page Image](https://bcdn.docswell.com/page/YE9WP9Z4E3.jpg)

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


# Page. 40

![Page Image](https://bcdn.docswell.com/page/GE8ND91V7D.jpg)

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


# Page. 41

![Page Image](https://bcdn.docswell.com/page/LELPMWQR7R.jpg)

演算・命令レベルの並列性
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


# Page. 42

![Page Image](https://bcdn.docswell.com/page/4JM4Y91P7W.jpg)

演算レベルの並列性
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


# Page. 43

![Page Image](https://bcdn.docswell.com/page/PJRW9GLY79.jpg)

演算レベルの並列性
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


# Page. 44

![Page Image](https://bcdn.docswell.com/page/PEXPQXW47X.jpg)

演算レベルの並列性
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


# Page. 45

![Page Image](https://bcdn.docswell.com/page/3EKD9WVPJD.jpg)

演算レベルの並列性
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


# Page. 46

![Page Image](https://bcdn.docswell.com/page/L73RW1M4J5.jpg)

演算レベルの並列性
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


# Page. 47

![Page Image](https://bcdn.docswell.com/page/87DYKX657G.jpg)

演算レベルの並列性
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


# Page. 48

![Page Image](https://bcdn.docswell.com/page/VJP6KPYDE8.jpg)

演算レベルの並列性
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


# Page. 49

![Page Image](https://bcdn.docswell.com/page/2EV3V2GG7Q.jpg)

演算レベルの並列性
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


# Page. 50

![Page Image](https://bcdn.docswell.com/page/57G3LLDDJL.jpg)

演算レベルの並列性
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


# Page. 51

![Page Image](https://bcdn.docswell.com/page/4EQ5YY1XJP.jpg)

演算レベルの並列性
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


# Page. 52

![Page Image](https://bcdn.docswell.com/page/KJ49WWR271.jpg)

演算レベルの並列性
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


# Page. 53

![Page Image](https://bcdn.docswell.com/page/LE1KYYQKJG.jpg)

演算レベルの並列性
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


# Page. 54

![Page Image](https://bcdn.docswell.com/page/GEWDGGMPJ2.jpg)

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


# Page. 55

![Page Image](https://bcdn.docswell.com/page/47ZGLLQ6E3.jpg)

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


# Page. 56

![Page Image](https://bcdn.docswell.com/page/YJ6YWW6L7V.jpg)

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


# Page. 57

![Page Image](https://bcdn.docswell.com/page/GJ5GMM6MJ4.jpg)

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


# Page. 58

![Page Image](https://bcdn.docswell.com/page/LE3RWWQ975.jpg)

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


# Page. 59

![Page Image](https://bcdn.docswell.com/page/8EDYKK98EG.jpg)

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


# Page. 60

![Page Image](https://bcdn.docswell.com/page/V7P6KKZWJ8.jpg)

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


# Page. 61

![Page Image](https://bcdn.docswell.com/page/2JV3VVW9EQ.jpg)

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


# Page. 62

![Page Image](https://bcdn.docswell.com/page/5EG3LLD47L.jpg)

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


# Page. 63

![Page Image](https://bcdn.docswell.com/page/4JQ5YY1R7P.jpg)

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


# Page. 64

![Page Image](https://bcdn.docswell.com/page/K749WWRQE1.jpg)

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


# Page. 65

![Page Image](https://bcdn.docswell.com/page/LJ1KYYQL7G.jpg)

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


# Page. 66

![Page Image](https://bcdn.docswell.com/page/GJWDGGMQ72.jpg)

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


# Page. 67

![Page Image](https://bcdn.docswell.com/page/4EZGLLQ3J3.jpg)

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


# Page. 68

![Page Image](https://bcdn.docswell.com/page/Y76YWW6ZEV.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 69

![Page Image](https://bcdn.docswell.com/page/G75GMM6974.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 70

![Page Image](https://bcdn.docswell.com/page/9J2Y99M5JR.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 71

![Page Image](https://bcdn.docswell.com/page/DEYG44X6EM.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 72

![Page Image](https://bcdn.docswell.com/page/VJNGYY5178.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 73

![Page Image](https://bcdn.docswell.com/page/YE9WPPYYE3.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 74

![Page Image](https://bcdn.docswell.com/page/GE8NDD6K7D.jpg)

ソフトウェアパイプライン
ここから数ページは、以下の簡単なループを実⾏するときのことを考えてみる
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


# Page. 75

![Page Image](https://bcdn.docswell.com/page/LELPMM9P7R.jpg)

ソフトウェアパイプライン
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


# Page. 76

![Page Image](https://bcdn.docswell.com/page/4JM4YYZ27W.jpg)

ソフトウェアパイプライン
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


# Page. 77

![Page Image](https://bcdn.docswell.com/page/PJRW996579.jpg)

ソフトウェアパイプライン
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


# Page. 78

![Page Image](https://bcdn.docswell.com/page/PEXPQQMX7X.jpg)

ソフトウェアパイプライン
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


# Page. 79

![Page Image](https://bcdn.docswell.com/page/3EKD99G9JD.jpg)

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


# Page. 80

![Page Image](https://bcdn.docswell.com/page/L73RWWN9J5.jpg)

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


# Page. 81

![Page Image](https://bcdn.docswell.com/page/87DYKKW87G.jpg)

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


# Page. 82

![Page Image](https://bcdn.docswell.com/page/VJP6KK9WE8.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 83

![Page Image](https://bcdn.docswell.com/page/2EV3VVM97Q.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 84

![Page Image](https://bcdn.docswell.com/page/57G3LLG4JL.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 85

![Page Image](https://bcdn.docswell.com/page/4EQ5YYXRJP.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 86

![Page Image](https://bcdn.docswell.com/page/KJ49WW6Q71.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 87

![Page Image](https://bcdn.docswell.com/page/LE1KYYVLJG.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 88

![Page Image](https://bcdn.docswell.com/page/GEWDGGLQJ2.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 89

![Page Image](https://bcdn.docswell.com/page/47ZGLLM3E3.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 90

![Page Image](https://bcdn.docswell.com/page/YJ6YWWNZ7V.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 91

![Page Image](https://bcdn.docswell.com/page/GJ5GMM59J4.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 92

![Page Image](https://bcdn.docswell.com/page/9E2Y99N5ER.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 93

![Page Image](https://bcdn.docswell.com/page/D7YG44P67M.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 94

![Page Image](https://bcdn.docswell.com/page/VENGYYM1J8.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 95

![Page Image](https://bcdn.docswell.com/page/Y79WPPNY73.jpg)

ソフトウェアパイプライン
それをするのを
ソフトウェアパイプライン
という
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


# Page. 96

![Page Image](https://bcdn.docswell.com/page/G78NDDKKJD.jpg)

ソフトウェアパイプライン
リカレンスがあるとソフトウェアパイプライン
できない
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


# Page. 97

![Page Image](https://bcdn.docswell.com/page/L7LPMMZPJR.jpg)

マシンの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


# Page. 98

![Page Image](https://bcdn.docswell.com/page/4EM4YYV2JW.jpg)

マシンの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


# Page. 99

![Page Image](https://bcdn.docswell.com/page/PERW9925J9.jpg)

マシンの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


# Page. 100

![Page Image](https://bcdn.docswell.com/page/P7XPQQDXJX.jpg)

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


# Page. 101

![Page Image](https://bcdn.docswell.com/page/37KD99X9ED.jpg)

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


# Page. 102

![Page Image](https://bcdn.docswell.com/page/LJ3RWW59E5.jpg)

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


# Page. 103

![Page Image](https://bcdn.docswell.com/page/8JDYKKD8JG.jpg)

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


# Page. 104

![Page Image](https://bcdn.docswell.com/page/VEP6KKXW78.jpg)

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


# Page. 105

![Page Image](https://bcdn.docswell.com/page/27V3VVL9JQ.jpg)

メモリとキャッシュ
キャッシュメモリは，メモリの⼀部のデータを選択的に保持している
より⾼速な記憶領域
「選択的に」というのはどうしているのか︖
メモリは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


# Page. 106

![Page Image](https://bcdn.docswell.com/page/5JG3LLX4EL.jpg)

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


# Page. 107

![Page Image](https://bcdn.docswell.com/page/47Q5YY8REP.jpg)

キャッシュの構造とラインアクセス
キャッシュの動作 Hitの場合
)*+
!
&quot;
・・・
・・・
・・・
・・・
386
13186
,,,
,,,
,,,
#$%&amp;&quot;&#039;(
・・・
・・・
•L
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
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


# Page. 108

![Page Image](https://bcdn.docswell.com/page/KE49WW2QJ1.jpg)

キャッシュの構造とラインアクセス
キャッシュの動作 Hitの場合
)*+
!
&quot;
・・・
・・・
・・・
・・・
386
13186
,,,
,,,
,,,
#$%&amp;&quot;&#039;(
・・・
・・・
•L
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
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


# Page. 109

![Page Image](https://bcdn.docswell.com/page/L71KYYMLEG.jpg)

キャッシュの構造とラインアクセス
キャッシュの動作 Hitの場合
)*+
!
&quot;
・・・
・・・
・・・
・・・
386
13186
,,,
,,,
,,,
#$%&amp;&quot;&#039;(
・・・
・・・
•L
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
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


# Page. 110

![Page Image](https://bcdn.docswell.com/page/G7WDGG3QE2.jpg)

キャッシュの構造とラインアクセス
キャッシュの動作 Hitの場合
)*+
•L
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
,,,
#$%&amp;&quot;&#039;(
!
&quot;
・・・
・・・
・・・
・・・
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


# Page. 111

![Page Image](https://bcdn.docswell.com/page/4JZGLLV373.jpg)

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


# Page. 112

![Page Image](https://bcdn.docswell.com/page/YE6YWW5ZJV.jpg)

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


# Page. 113

![Page Image](https://bcdn.docswell.com/page/GE5GMMY9E4.jpg)

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


# Page. 114

![Page Image](https://bcdn.docswell.com/page/972Y99G57R.jpg)

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


# Page. 115

![Page Image](https://bcdn.docswell.com/page/DJYG44V6JM.jpg)

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


# Page. 116

![Page Image](https://bcdn.docswell.com/page/V7NGYYG1E8.jpg)

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


# Page. 117

![Page Image](https://bcdn.docswell.com/page/YJ9WPPWYJ3.jpg)

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


# Page. 118

![Page Image](https://bcdn.docswell.com/page/GJ8NDDNKED.jpg)

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


# Page. 119

![Page Image](https://bcdn.docswell.com/page/LJLPMMPPER.jpg)

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


# Page. 120

![Page Image](https://bcdn.docswell.com/page/47M4YY42EW.jpg)

キャッシュの構造とラインアクセス
キャッシュスラッシング
キャッシュの同じラインへのデータの出し入れが頻発することを
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


# Page. 121

![Page Image](https://bcdn.docswell.com/page/P7RW99W5E9.jpg)

キャッシュの構造とラインアクセス
ループが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
&quot;
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
8192
,,,
,,,
Miss
,,,
#$%&amp;&quot;&#039;(
121


# Page. 122

![Page Image](https://bcdn.docswell.com/page/PJXPQQPXEX.jpg)

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


# Page. 123

![Page Image](https://bcdn.docswell.com/page/3JKD99D97D.jpg)

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


# Page. 124

![Page Image](https://bcdn.docswell.com/page/LE3RWWR975.jpg)

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


# Page. 125

![Page Image](https://bcdn.docswell.com/page/8EDYKKY8EG.jpg)

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


# Page. 126

![Page Image](https://bcdn.docswell.com/page/V7P6KK6WJ8.jpg)

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


# Page. 127

![Page Image](https://bcdn.docswell.com/page/2JV3VV39EQ.jpg)

キャッシュの構造とラインアクセス
キャッシュスラッシング回避
配列の先頭アドレスをずらそう
ここでは，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


# Page. 128

![Page Image](https://bcdn.docswell.com/page/5EG3LL347L.jpg)

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


# Page. 129

![Page Image](https://bcdn.docswell.com/page/4JQ5YY5R7P.jpg)

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


# Page. 130

![Page Image](https://bcdn.docswell.com/page/K749WW9QE1.jpg)

キャッシュの構造とラインアクセス
ループが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
!
&quot;
8192
16384
#$%&amp;!
#$%&amp;&quot;
#$%&amp;&#039;
24577
,,,
,,,
Hit
Hit
DO i=1, 131072
tmp1=A(1)
tmp2=B(1)
tmp3=C(1)
・・・
ENDDO
以降i=17までキャッシュミスなし
,,,
#$%&amp;&quot;&#039;(
130


# Page. 131

![Page Image](https://bcdn.docswell.com/page/LJ1KYYKL7G.jpg)

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


# Page. 132

![Page Image](https://bcdn.docswell.com/page/GJWDGGDQ72.jpg)

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


# Page. 133

![Page Image](https://bcdn.docswell.com/page/4EZGLLG3J3.jpg)

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


# Page. 134

![Page Image](https://bcdn.docswell.com/page/Y76YWWYZEV.jpg)

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


# Page. 135

![Page Image](https://bcdn.docswell.com/page/G75GMMG974.jpg)

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


# Page. 136

![Page Image](https://bcdn.docswell.com/page/9J2Y99Y5JR.jpg)

ストリームの考え⽅
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


# Page. 137

![Page Image](https://bcdn.docswell.com/page/DEYG44G6EM.jpg)

ストリームの考え⽅
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


# Page. 138

![Page Image](https://bcdn.docswell.com/page/VJNGYY8178.jpg)

ストリームの考え⽅
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


# Page. 139

![Page Image](https://bcdn.docswell.com/page/YE9WPPKYE3.jpg)

ストリームの考え⽅
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


# Page. 140

![Page Image](https://bcdn.docswell.com/page/GE8NDDRK7D.jpg)

ストリームの考え⽅
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


# Page. 141

![Page Image](https://bcdn.docswell.com/page/LELPMMKP7R.jpg)

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


# Page. 142

![Page Image](https://bcdn.docswell.com/page/4JM4YY227W.jpg)

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


# Page. 143

![Page Image](https://bcdn.docswell.com/page/PJRW99M579.jpg)

ストリームの考え⽅
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


# Page. 144

![Page Image](https://bcdn.docswell.com/page/PEXPQQVX7X.jpg)

ストリームの考え⽅
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


# Page. 145

![Page Image](https://bcdn.docswell.com/page/3EKD99Q9JD.jpg)

プリフェッチ
• ソフトウェアパイプラインはロード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


# Page. 146

![Page Image](https://bcdn.docswell.com/page/L73RWWP9J5.jpg)

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


# Page. 147

![Page Image](https://bcdn.docswell.com/page/87DYKKL87G.jpg)

プリフェッチ
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


# Page. 148

![Page Image](https://bcdn.docswell.com/page/VJP6KK2WE8.jpg)

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


