2017/5/15

講習会：KNL実践

1

第77回 お試しアカウント付き
並列プログラミング講習会「KNL実践」
東京大学情報基盤センター

内容に関するご質問はhanawa ＠ cc.u-tokyo.ac.jp
まで、お願いします。

2017/5/15

講習会：KNL実践

2

講習会概略• 開催日：

2017年 5月15日（月） 10：00 - 18：00• 場所：東京大学情報基盤センター 4階 413遠隔会義室• 講師：塙 敏博• 講習会プログラム：
9：30 - 10：00 受付• 10：00 - 12：00 Oakforest-PACSログイン、Oakforest-PACSシステム紹介、KNL概要• (12：00 - 13：30 昼休憩)
• 13：30 - 15：00 KNLにおける最適化（講義＋演習）• (15：00 - 15：15 休憩)• 15：15 - 18：00 Oakforest-PACSでのハイブリッド並列化と最適化(講義+演習)•2017/5/15

講習会：KNL実践

3

Oakforest-PACS利用の準備
配布資料「Oakforest-PACS利用の手引き」参照2017/5/15

講習会：KNL実践

ユーザ名の確認• 本講習会でのユーザー名

利用者番号 : t00711～
利用グループ： gt00

4

2017/5/15

講習会：KNL実践

5

東大スーパーコンピュータの概略

2017/5/15

講習会：KNL実践

6

東大センターのスパコン
2基の大型システム，6年サイクル
FY
08 09 10 11 12 13 14 15 16 17 18 19 20 21 22
Hitachi SR11K/J2
IBM Power-5+
18.8TFLOPS,
16.4TB

Yayoi: Hitachi SR16000/M1
IBM Power-7
54.9 TFLOPS, 11.2 TB

Hitachi HA8000 (T2K)
AMD Opteron

メニーコア型大規模
スーパーコンピュータ

Oakforest-PACS
Fujitsu, Intel KNL

25PFLOPS, 919.3TB

140TFLOPS, 31.3TB
Oakleaf-FX: Fujitsu PRIMEHPC
FX10, SPARC64 IXfx
1.13 PFLOPS, 150 TB

Oakbridge-FX

JCAHPC:
筑波大・
東大

BDEC system

50+ PFLOPS (?)

Big Data &Extreme Computing

136.2 TFLOPS, 18.4
TB
Reedbush, SGI
データ解析・シミュレーション
Broadwell + Pascal
融合スーパーコンピュータ

1.93 PFLOPS
Reedbush-L
長時間ジョブ実行用演算加速装置
Pascal 1.4+PF付き並列スーパーコンピュータ

Peta

K

K computer

Post-K ?

2017/5/15

講習会：KNL実践

75システム運用中• Yayoi (日立 SR16000, IBM Power7)• 54.9 TF, 2011年11月 〜 2017年10月• Oakleaf-FX (富士通 PRIMEHPC FX10)• 1.135 PF, 京コンピュータ商用版, 2012年4月 〜 2018年3月• Oakbridge-FX (富士通 PRIMEHPC FX10)• 136.2 TF, 長時間実行用（168時間）, 2014年4月 〜 2018年3月• Reedbush (SGI, Intel BDW + NVIDIA P100 (Pascal))• データ解析・シミュレーション融合スーパーコンピュータ• 1.93 PF, 2016年7月〜 2020年6月• 東大ITC初のGPUシステム (2017年3月より), DDN IME (Burst
Buffer)• Oakforest-PACS (OFP) (富士通、Intel Xeon Phi (KNL))• JCAHPC (筑波大CCS＆東大ITC)• 25 PF, TOP 500で6位 (2016年11月) (日本で1位)• Omni-Path アーキテクチャ, DDN IME (Burst Buffer)2017/5/15

講習会：KNL実践

8東京大学情報基盤センター
スパコン（1/3）

Fujitsu PRIMEHPC FX10 （FX10スーパーコンピュータシステム）

Total Peak performance: 1.13 PFLOPS
Total number of nodes: 4,800
Total memory: 150TB
Peak performance per node : 236.5 GFLOPSMain memory per node
: 32 GBDisk capacity: 2.1 PBSPARC64 IXfx 1.848GHz

2012年7月~2018年3月（予定）

Oakbridge-FX
長時間ジョブ用のFX10
ノード数：24～576
制限時間：最大168時間
（１週間）

8

2017/5/15

講習会：KNL実践

9東京大学情報基盤センター
スパコン（2/3-1）

Reedbush-U （SGI Rackable クラスタシステム ）Total Peak performance: 508 TFLOPS
Total number of nodes: 420
Total memory: 105 TB
Peak performance per node : 1209.6 GFLOPSMain memory per node
: 256 GBDisk capacity: 5.04 PB
File Cache system (SSD): 230 TBIntel Xeon E5-2695v4 2.1GHz 18 core x2 socket

2016年7月1日試験運転開始
2016年9月1日正式運用開始

9

2017/5/15

講習会：KNL実践

10東京大学情報基盤センター
スパコン（2/3-2）

Reedbush-H （SGI Rackable クラスタシステム ）Total Peak performance: 145 TFLOPS+ 1272 TFLOPS
Total number of nodes: 120
Total memory: 30 TB + 8 TB
Peak performance per node : 1209.6 GFLOPS+ 10.6 TFLOPSMain memory per node
: 256 GB+ 32 GBDisk capacity (shared w/ U) : 5.04 PB
File Cache system (SSD, (shared w/ U): 230 TBIntel Xeon E5-2695v4 2.1GHz 18 core x2 socket+ NVIDIA Tesla P100 with NVLink x 2

2017年3月1日試験運転開始
2017年4月3日正式運用開始

10

2017/5/15

講習会：KNL実践

1111東京大学情報基盤センター
筑波大学計算科学研究センター
スパコン (3/3)と共同運用
Oakforest-PACS （Fujitsu PRIMERGY CX600）
Total Peak performance: 25 PFLOPS
Total number of nodes: 8,208
Total memory: 897.7 TB
Peak performance per node : 3.046 TFLOPSMain memory per node
: 96 GB (DDR4)+ 16 GB(MCDRAM)
Disk capacity: 26.2 PB
File Cache system (SSD): 960 TBIntel Xeon Phi 7250 1.4 GHz 68 core x1 socket

2016年12月1日試験運転開始
2017年4月3日正式運用開始

2017/5/15

12

講習会：KNL実践

FX10計算ノードの構成

TOFU
Network

1ソケットのみ

各ＣＰＵの内部構成

20GB/秒

Core
#0

Core
#1

Core
#2

Core
#3

…

Core
#12

Core
#13

Core
#14

Core
#15

L1

L1

L1

L1

: L1データキャッシュ32KB

L1

L1

L1

L1

ICC

L2 (16コアで共有、12MB)

85GB/秒=(8Byte×1333MHz
×8 channel)

MemoryMemoryMemoryMemory4GB ×2枚

4GB ×2枚

4GB ×2枚

4GB ×2枚

ノード内合計メモリ量：8GB×4＝32GB

DDR3 DIMM

2017/5/15

講習会：KNL実践

FX10の通信網（１TOFU単位）
１TOFU単位ノード

計算ノード内
ノード

ノード

ノード
ノード
ノード

ノード

ノード

1TOFU単位
間の結合用

ノード

ノード

ノード

13

ノード

ノード

6本それぞれ5GB/秒（双方向）2017/5/15

講習会：KNL実践

14

FX10の通信網（１TOFU単位間の結合）
３次元接続
１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１１
TOFU
TOFU
単位
単位

１１
TOFU
TOFU
単位
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１１
TOFU
TOFU
単位
単位

１１
TOFU
TOFU
単位
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

１
TOFU
単位

l ユーザから見ると、X軸、Y軸、Z軸について、
奥の1TOFUと、手前の１TOFUは、繋がってみえます（３次元トーラス接続）
l ただし物理結線では
l X軸はトーラス
l Y軸はメッシュ
l Z軸はメッシュまたは、トーラスになっています2017/5/15

15

講習会：KNL実践

Reedbush-Uノードのブロック図• メモリのうち、「近い」メモリと「遠い」メモリがある=> NUMA (Non-Uniform Memory Access)(FX10はフラット)

メモリ
128GB

DDR4
DDR4
DDR4
DDR4

G3 x16

76.8GB/sIntel Xeon
E5-2695 v4(BroadwellEP)
15.7 GB/s

IB EDR
HCA

76.8GB/s
QPI
QPI
76.8GB/sIntel Xeon
E5-2695 v4(BroadwellEP)

DDR4
DDR4
DDR4
DDR4

76.8GB/s

メモリ
128GB

2017/5/15

Broadwell-EPの構成

Core
#0

L L
1 2

L3

Core
#5

L L
1 2

Core
#1

L L
1 2

L3

Core
#6

L L
1 2

Core
#2

L L
1 2

L3

Core
#7

L L
1 2

Core
#3

L L
1 2

L3

Core
#8

L L
1 2

Core
#4

L L
1 2

L3

Memory１ソケットのみを図示

コア当たりL1データ: 2KB, L2: 256KB,
L3: 2.5MB(共有) => L3 は全体で45MB

PCIe

QPI x2

DDR4
DIMM

16

講習会：KNL実践

L3

Core
#9

L L
1 2

L3

Core
#14

L L
1 2

L3

L3

Core
#10

L L
1 2

L3

Core
#15

L L
1 2

L3

L3

Core
#11

L L
1 2

L3

Core
#16

L L
1 2

L3

L3

Core
#12

L L
1 2

L3

Core
#17

L L
1 2

L3

Core
#13

L L
1 2

L3

Memory16GB ×2枚
16GB ×2枚
ソケット当たりメモリ量：16GB×8＝128GB

MemoryMemory16GB ×2枚
16GB ×2枚
76.8 GB/秒=(8Byte×2400MHz×4 channel)

2017/5/15

講習会：KNL実践

17

Reedbush-Uの通信網• フルバイセクションバンド幅を持つFat Tree網• どのように計算ノードを選んでも互いに無衝突で通信が可能• Mellanox InfiniBand EDR 4x CS7500: 648ポート• 内部は36ポートスイッチ (SB7800)を (36+18)台組み合わせたものと等価
648ポートDirectorスイッチ 1台の中身
...

36ポート
Spineスイッチ
18台

...

36ポート
Leaf スイッチ
36台

Uplink: 18

Downlink: 18

1

...

18

19

...

36

37

...

54

2017/5/15

18

講習会：KNL実践

Reedbush-Hノードのブロック図
メモ
リ
128G
B

DDR4
DDR4
DDR4
DDR4

Intel Xeon
E5-2695 v4(BroadwellEP)

QPI
76.8GB/s

15.7 GB/s

15.7 GB/s

メモ
リ
128G
B

76.8GB/s

20 GB/s
NVLinK
NVLinK
20 GB/s
EDR switch

G3
x16

G3
x16

NVIDIA
Pascal

DDR4
DDR4
DDR4
DDR4

PCIe sw

PCIe sw

IB FDR
HCA

G3
x16

G3
x16

76.8GB/s

76.8GB/s
QPIIntel Xeon
E5-2695 v4(BroadwellEP)

NVIDIA
PascalIB FDR
HCA

EDR

2017/5/15

19

講習会：KNL実践

Knights Landing: Next Intel® Xeon Phi™ Processor

Oakforest-PACS 計算ノード
Intel® Many-Core Processor targeted for HPC and SupercomputingFirst self-boot Intel® Xeon Phi™ processor that is binary
compatible with main line IA. Boots standard OS.

Significant improvement in scalar and vector performance• Intel XeonIntegration
Phi of(Knights
Landing)Memory on package:innovative memoryarchitecture for high bandwidth and high capacity• 1ノード1ソケット
Integration of Fabric on package
Three products• MCDRAM: オンパッケージKNL Self-Boot

KNL Self-Boot w/ Fabric

KNL Card(Fabric Integrated)(PCIe-Card)の高バンド幅メモリ16GB+ DDR4メモリ(Baseline)

HotChips27
Knights Landing
Overview
KNLスライドより
MCDRAMMCDRAM

2 x16
1 x4

X4
DMI

PCIe
Gen 3

D
M
I

MCDRAMMCDRAM

Potential future options subject to change without notice.
All timeframes, features, products and dates are preliminary forecasts and subject to change without further notification.

EDC

ソケット当たりメモリ量:
16GB×6＝96GB

3

Core

C
H
A
N
N
E
L
S

2 VPU
1MB
L2

MCDRAM

4

EDC

3
D
D
R
4

36 Tilesconnected by
2D MeshInterconnect

DDR MC

EDC

Core

EDC

Tile

D
D
R
4

MCDRAM: 490GB/秒以上 （実測）DDR4: 115.2 GB/秒=(8Byte×2400MHz×6 channel)
2 VPU

EDC

EDC

MCDRAM

Omni-path not shown

misc

Package

DDR MCEDC

MCDRAM

C
H
A
N
N
E
L
S

EDC

MCDRAM2017/5/15

20

講習会：KNL実践

Oakforest-PACS: Intel Omni-Path Architecture による
フルバイセクションバンド幅Fat-tree網
768 port Director
Switch12台(Source by Intel)

22Uplink: 24

48 port Edge Switch
362 台
Downlink: 24
1

...

24

25

...

48

49

...

72

計算ノード
ラックに分散コストはかかるがフルバイセクションバンド幅を維持• システム全系使用時にも高い並列性能を実現• 柔軟な運用：ジョブに対する計算ノード割り当ての自由度が高い

2017/5/15

講習会：KNL実践

21

東大情報基盤センターOakforest-PACSスーパーコ
ンピュータシステムの料金表（2017年4月1日 ）• パーソナルコース（年間）• コース１： 100,000円 ： 8ノード(基準)、最大16ノードまで• コース２： 200,000円 ： 16ノード(基準)、最大64ノードまで• グループコース• 400,000円 (企業 480,000円) ： 1口 8ノード（基準）、最大128ノー
ドまで• 以上は、「トークン制」で運営• 申し込みノード数×360日×24時間の「トークン」が与えられる• 基準ノードまでは、トークン消費係数が1.0• 基準ノードを超えると、超えた分は、消費係数が2.0になる• 大学等のユーザはFX10、Reedbushとの相互トークン移行も可能

2017/5/15

講習会：KNL実践

22

東大情報基盤センターReedbushスーパーコン
ピュータシステムの料金表（2017年4月1日 ）• パーソナルコース（年間）• 150,000円：RB-U: 4ノード（基準）、最大16ノードまで
RB-H: 1ノード（基準）、最大2ノードまで• グループコース• 300,000円：1口 4ノード（基準）、最大128ノードまで、
RB-H：1ノード（基準）、最大32ノードまで（トークン係数はUの2.5倍）• RB-Uのみ 企業 360,000円 ： 1口 4ノード（基準）、最大128ノードまで• RB-Hのみ 企業 216,000円 ： 1口 1ノード（基準）、最大32ノードまで• 以上は、「トークン制」で運営• 申し込みノード数×360日×24時間の「トークン」が与えられる• 基準ノードまでは、トークン消費係数が1.0• 基準ノードを超えると、超えた分は、消費係数が2.0になる• 大学等のユーザはFX10, Oakforest-PACSとの相互トークン移行も可能• ノード固定もあり

2017/5/15

講習会：KNL実践

23

東大情報基盤センターFX10スーパーコン
ピュータシステムの料金表（2017年4月1日）• パーソナルコース（年間）• コース１：90,000円 ： 12ノード(基準)、最大24ノードまで• コース２： 180,000円 ： 24ノード(基準)、最大96ノードまで• グループコース• 360,000円 (企業 432,000円) ：1口、12ノード、最大1440ノードまで• 以上は、「トークン制」で運営• 申し込みノード数×360日×24時間の「トークン」が与えられる• 基準ノードまでは、トークン消費係数が1.0• 基準ノードを超えると、超えた分は、消費係数が2.0になる• 大学等のユーザはReedbush, Oakforest-PACSとの相互トークン

移行も可能2017/5/15

講習会：KNL実践

24

スーパーコンピュータシステムの詳細• 以下のページをご参照ください• 利用申請方法• 運営体系• 料金体系• 利用の手引などがご覧になれます。
http://www.cc.u-tokyo.ac.jp/system/ofp/
http://www.cc.u-tokyo.ac.jp/system/reedbush/
http://www.cc.u-tokyo.ac.jp/system/fx10/

2017/5/15

講習会：KNL実践

25

トライアルユース制度について• 安価に当センターのOakleaf/Oakbridge-FX, Reedbush-U/H, Oakforest-PACS

システムが使える「無償トライアルユース」および「有償トライアルユー
ス」制度があります。
• アカデミック利用• パーソナルコース、グループコースの双方（1ヶ月～3ヶ月）• 企業利用• パーソナルコース（１ヶ月～３ヶ月）（FX10: 最大24ノード、最大96ノード,

RB-U: 最大16ノード, RB-H: 最大2ノード、OFP: 最大16ノード, 最大64ノー
ド）
本講習会の受講が必須、審査無• グループコース• 無償トライアルユース：（１ヶ月～３ヶ月）：無料（FX10:最大1,440ノード、
RB-U: 最大128ノード、RB-H: 最大32ノード、OFP: 最大2048ノード）• 有償トライアルユース：（１ヶ月～最大通算９ヶ月）、有償（計算資源は無償と同等）• スーパーコンピュータ利用資格者審査委員会の審査が必要（年2回実施）• 双方のコースともに、簡易な利用報告書の提出が必要

2017/5/15

講習会：KNL実践

26

並列プログラミングの基礎

2017/5/15

講習会：KNL実践

27

並列プログラミングとは何か？
• 逐次実行のプログラム（実行時間T ）を、ｐ台の計算機を使って、T / ｐ にすること。

T

T / ｐ
• 素人考えでは自明。
• 実際は、できるかどうかは、対象処理の内容（アルゴリズム）で大きく難しさが違う• アルゴリズム上、絶対に並列化できない部分の存在• 通信のためのオーバヘッドの存在• 通信立ち上がり時間• データ転送時間

2017/5/15

講習会：KNL実践

28

並列計算機の分類• Michael J. Flynn教授（スタンフォード大）の分類(1966)• 単一命令・単一データ流（SISD, Single Instruction Single Data Stream）• 単一命令・複数データ流（SIMD, Single Instruction Multiple Data Stream）• 複数命令・単一データ流（MISD, Multiple Instruction Single Data Stream）• 複数命令・複数データ流（MIMD, Multiple Instruction Multiple Data Stream）

2017/5/15

講習会：KNL実践

29

並列計算機のメモリ型による分類
A) メモリアドレスを共有：互いのメモリがアクセス可能
1. 共有メモリ型（SMP:
Symmetric Multiprocessor,
UMA: Uniform Memory Access）
2. 分散共有メモリ型（DSM:
Distributed Shared Memory）
共有・非対称メモリ型（ccNUMA、
Cache Coherent Non-Uniform
Memory Access）

2017/5/15

講習会：KNL実践

30

並列計算機のメモリ型による分類
B) メモリアドレスは独立：互いのメモリはアクセス不可
3. 分散メモリ型（メッセージパッシング）

2017/5/15

講習会：KNL実践

31

並列プログラミングのモデル• 実際の並列プログラムの挙動はMIMD• アルゴリズムを考えるときは＜SIMDが基本＞• 複雑な挙動は人間には想定し難い

2017/5/15

講習会：KNL実践

32

並列プログラミングのモデル• 多くのMIMD上での並列プログラミングのモデル
1. SPMD（Single Program Multiple Data）• １つの共通のプログラムが、並列処理開始時に、
全プロセッサ上で起動する• MPI（バージョン１）のモデル

2. Master / Worker（Master / Slave）• １つのプロセス（Master）が、複数のプロセス（Worker）を管理（生成、消去）する。

2017/5/15

講習会：KNL実践

33

並列プログラムの種類• マルチプロセス• MPI （Message Passing Interface）• HPF （High Performance Fortran）• 自動並列化Fortranコンパイラ• ユーザがデータ分割方法を明示的に記述プロセスとスレッドの違い•メモリを意識するかどうかの違い•別メモリは「プロセス」•同一メモリは「スレッド」• マルチスレッド• Pｔhread (POSIX スレッド)• Solaris Thread (Sun Solaris OS用)• NT thread (Windows NT系、Windows95以降)• スレッドの Fork（分離） と Join（融合） を明示的に記述• Java• 言語仕様としてスレッドを規定• OpenMP• ユーザが並列化指示行を記述

マルチプロセスとマルチスレッドは共存可能→ハイブリッドMPI/OpenMP実行2017/5/15

34

講習会：KNL実践

並列処理の実行形態（１）• データ並列• データを分割することで並列化する。
• データの操作（＝演算）は同一となる。
• データ並列の例：行列－行列積

SIMDの考え方と同じæ 1 2 3 ö æ 9 8 7 ö æç 1* 9 + 2 * 6 + 3 * 3 1* 8 + 2 * 5 + 3 * 2 1* 7 + 2 * 4 + 3 *1 ö÷ç÷ ç÷ ＝ ç 4 * 9 + 5 * 6 + 6 * 3 4 * 8 + 5 * 5 + 6 * 2 4 * 7 + 5 * 4 + 6 *1÷
ç 4 5 6 ÷ ç 6 5 4 ÷ ç 7 * 9 + 8 * 6 + 9 * 3 7 * 8 + 8 * 5 + 9 * 2 7 * 7 + 8 * 4 + 9 *1÷
øç7 8 9÷ ç 3 2 1÷ è
è
ø è
ø
●並列化
CPU０ æ 1

2 3ö
ç÷
CPU１ ç 4 5 6 ÷
CPU２ ç 7 8 9 ÷èø

全CPUで共有

æ9 8 7öæ 1* 9 + 2 * 6 + 3 * 3 1* 8 + 2 * 5 + 3 * 2 1* 7 + 2 * 4 + 3 *1 öç
÷ ＝ çç 4 * 9 + 5 * 6 + 6 * 3 4 * 8 + 5 * 5 + 6 * 2 4 * 7 + 5 * 4 + 6 *1÷÷
ç 6 5 4÷
ç 7 * 9 + 8 * 6 + 9 * 3 7 * 8 + 8 * 5 + 9 * 2 7 * 7 + 8 * 4 + 9 *1÷
èø
ç3 2 1÷èø 並列に計算：初期データは異なるが演算は同一

2017/5/15

35

講習会：KNL実践

並列処理の実行形態（２）• タスク並列• タスク（ジョブ）を分割することで並列化する。
• データの操作（＝演算）は異なるかもしれない。
• タスク並列の例：カレーを作る• 仕事１：野菜を切る• 仕事２：肉を切る• 仕事３：水を沸騰させる• 仕事４：野菜・肉を入れて煮込む• 仕事５：カレールゥを入れる

●並列化

仕事１
仕事２
仕事３

仕事４

仕事５

時間

2017/5/15

性能評価指標並列化の尺度

講習会：KNL実践36

2017/5/15

37

講習会：KNL実践

性能評価指標－台数効果• 台数効果 S P = TS / TP (0 £ S p )
• 式：
• TS
：逐次の実行時間、：P台での実行時間
TP• P台用いて S P = Pのとき、理想的な（ideal）速度向上• P台用いて S P > Pのとき、スーパリニア・スピードアップ• 主な原因は、並列化により、データアクセスが局所化されて、キャッシュヒット率が向上することによる高速化• 並列化効率• 式： E P = S P / P ´ 100 (0 £ E p ) [%]• 飽和性能• 速度向上の限界• Saturation, 「さちる」
Ｐ2017/5/15

講習会：KNL実践

38

アムダールの法則• 逐次実行時間を K とする。

そのうち、並列化ができる割合を α とする。
• このとき、台数効果は以下のようになる。

S P = K /(Ka / P + K (1 - a ))= 1 /(a / P + (1 - a )) = 1 /(a (1 / P - 1) + 1)
• 上記の式から、たとえ無限大の数のプロセッサを使っても（P→∞）、台数効果は、高々 1/(1-α) である。
（アムダールの法則）• 全体の90%が並列化できたとしても、無限大の数のプロセッサをつかっても、 1 / (1 - 0.9) = 10 倍 にしかならない！
→高性能を達成するためには、少しでも並列化効率を上げる
実装をすることがとても重要である

2017/5/15

39

講習会：KNL実践

アムダールの法則の直観例
並列化できない部分（１ブロック） 並列化できる部分（８ブロック）●逐次実行＝88.8%が並列化可能●並列実行（４並列）

9/3=3倍●並列実行（８並列）

9/2=4.5倍 ≠ 6倍2017/5/15

講習会：KNL実践

40

本講習会の目的
並列アルゴリズムはひとまず置いといて…

KNLの多数のコアの扱い方、Oakforest-PACSの多数の計算ノードを組み合わせて、効率良く扱う手法を学ぼう！
• その他の講習会 (予定) http://www.cc.u-tokyo.ac.jp/support/kosyu/• 並列アルゴリズムを学びたい方• 7/11,12 OpenMP/OpenACCによるマルチコア・メニィコア並列プログラミ

ング入門
• その他
• 5/23,24 「並列有限要素法とハイブリッド並列プログラミング」• 6/1,2
MPI 基礎• 6/26,27 MPI 上級編• 7/18,19 GPUクラスタ講習会(仮称)「こんな講習会が欲しい！」という要望があればぜひア
ンケートへ！

2017/5/15

講習会：KNL実践

KNLおよびOakforest-PACS概要

41

2017/5/15

42

講習会：KNL実践

Intel Xeon Phi (KNL: Knights Landing)l® Xeon Phi™ Processor

rgeted for HPC and Supercomputingthat is binary
ard OS.

• Atom (Silvermont) コア

ctor performance+ AVX512
TILE x2
2 VPU

ative memory
apacity

Knights Landing Overview• 2コア 1タイル

Core
• 各コアは 4スレッド

KNL Card(PCIe-Card)

notice.
o change without further notification.

MCDRAMEDC

MCDRAM

EDC

3

X4
DMI

PCIe
Gen 3

D
M
I

MCDRAMEDC

MCDRAM

EDC

EDC

EDC

misc

Core

(HyperThreading)

配布資料から
Chip: 36 Tiles interconnected by
2D Mesh• 64, 68コア
アップデート
Tile: 2 Cores + 2 VPU/core + 1 MB
L2（32, 34タイル）•Memory:
MCDRAM:
オンパッケージMCDRAM:
16 GB on-package; High BW
KNL✝ コア の高バンド幅メモリ16GB+
DDR4: 6 channels @ 2400 up to 384GB
4-way ハイパースレッディング(最大 4 × 72 = 288 論理プロセ
DDR4メモリ
IO:
36 lanes PCIe Gen3. 4 lanes of DMI for chipset
DDR
436 Tilesconnected by
2D MeshInterconnect

DDR MC

1MB
L2

2 VPU

3

Tile

D
D
R
4
C
H
A
N
N
E
L
S

2 x16
1 x4

CHA

DDR MC

EDC

C
H
A
N
N
E
L
S

EDC

L2 キャッシュはタイル上の 2 つのコアで共有される

Node: 1-Socket only
タイル コアアウト
アウト
コア Omni-Path
Fabric:on-package(not shown)オブオブ
命令キャッシュ命令キャッシュ

オーダー

オーダー

デコード
+ リタイヤデコード+ リタイヤVector Peak Perf: 3+TF DP and 6+TF SP Flops
1MiB
ベクトル
Scalar
Perf: ~3xover Knights
Corner ベクトル
ベクトル
ベクトル
L2
ALU
ALU
ALU Triad (GB/s):データ
ALU
Streams
MCDRAM:
400+;
DDR: 90+
レガシー
レガシー
キャッシュ

MCDRAM

4

MCDRAM

Omni-path not shown

Package

MCDRAMMCDRAM

Source Intel: All products, computer systems, dates and figures specified are preliminary based on current expectations,
HW + SWbased on current
L1 without
データキャッシュ
32KiBexpectations
L1 データキャッシュ
are subject 32KiB
to change
notice. KNL data are preliminary
and are subject to change
プリフェッチwithout notice. 1Binary Compatible with Intel Xeon processors
using Haswell Instruction Set (except TSX). 2Bandwidth
numbers are based on STREAM-like memory access pattern when MCDRAM used as flat memory. Results have been
HW + SWestimated based on internal Intel analysis
and are provided for informational
purposes only. Any difference in system
メッシュへ
hardware or software design or configuration may affect actual プリフェッチ
performance.

出典：左：HotChips 27 KNLスライド,
右：Colfax (翻訳：エクセルソフト)
colfaxresearch.com/knl-webinar
KNL コアの機能✝

© Colfax I2017/5/15

講習会：KNL実践

43

KNLの動作モード• メモリモード：3種類• Flat:MCDRAMとDDR4 が独立したアドレス• Cache: MCDRAMはDDR4メモリのキャッシュとして動作• Hybrid• クラスタリングモード: 5種類• (All-to-all: アドレス情報が全体に分散… 非推奨)
• Quadrant, Hemisphere: 内部でアドレス情報が4(または2)に分割（ユーザからは見えない）• SNC-4, SNC-2: NUMAドメインが明示的に4 (or 2)に分割

モードの変更には再起動が必要=> ジョブスケジューラによりプロビジョニング（現時点では、各モードのジョブキューを用意）2017/5/15

講習会：KNL実践

44

メモリモード• Cacheモード• MCDRAMはL3キャッシュとして動作• Flatモード• MCDRAMを明示的に使い分け
MCDRAM
16 GB

MCDRAM
16 GB

DDR4
96 GB

DDR4
96 GB

物理
アドレス

2017/5/15

45

講習会：KNL実践

クラスタリングモード

現在OFPではQuadrantのみ
Cluster
Mode: Sub-NUMA C• Quadrant: ソフトウェ

アからはフラットなメ
モリ空間に見える• 内部では4分割、格納先のMCDRAMと同じ領域にキャッシュ情報（タ
グ）を配置

OPIO
MCDRAMOPIO
MCDRAMOPIO
MCDRAM

PCIe

EDC

EDC

IIO

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

iMC

Tile

Tile

OPIO
MCDRAM

EDC

EDC

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

3
1

4

2
iMC

DDR

• SNC-4: 4つのNUMAド

メインに見える• 4ソケットある場合と同

じ

DDR
Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

Tile

EDC

EDC

Misc

EDC

EDC

OPIO
MCDRAMOPIO
MCDRAMOPIO
MCDRAMOPIO
MCDRAM

HotChips27
1) L2 miss, 2) Directory access, 3) Memory
access, 4) Data return
KNLスライドより162017/5/15

講習会：KNL実践

Stream Triad性能の比較• DDR4: micprun -D -k stream• MCDRAM: micprun -k stream• unset KMP_AFFINITY• export KMP_HW_SUBSET=66c@2,1t
タイル0を避ける設定

DDR4
Cache
Flat

MCDRAM
342.6 GB/sec
84.8 GB/sec 492.1 GB/sec

46

2017/5/15

講習会：KNL実践

47

Oakforest-PACS の仕様
総ピーク演算性能

25 PFLOPS

ノード数
Product
計算
ノード

8,208

プロセッサ

メモ
リ

高バンド
幅
低バンド
幅

相互結 Product
合網
リンク速度
トポロジ

富士通 PRIMERGY CX600 M1 (2U)
+ CX1640 M1 x 8node
Intel® Xeon Phi™ 7250
（開発コード: Knights Landing）
68 コア、1.4 GHz
16 GB, MCDRAM, 実効 490 GB/sec
96 GB, DDR4-2400, ピーク 115.2
GB/secIntel® Omni-Path Architecture
100 Gbps
フルバイセクションバンド幅Fat-tree2017/5/15

講習会：KNL実践

48

Oakforest-PACS の仕様（続き）
並列ファイ Type
ルシステム 総容量
Product

Lustre File System
26.2 PB
DataDirect Networks SFA14KE

総バンド幅 500 GB/sec
Burst Buffer, Infinite Memory Engine
高速ファイ Type(by DDN)
ルキャッ
シュシステ 総容量
940 TB (NVMe SSD, パリティを含ム
む)Product
DataDirect Networks IME14K
総バンド幅 1,560 GB/sec
総消費電力4.2MW（冷却を含む）
102
総ラック数

2017/5/15

講習会：KNL実践

49

Oakforest-PACS のソフトウェア• OS: Red Hat Enterprise Linux (ログインノード)、

CentOS および McKernel (計算ノード、切替可能)• McKernel: 理研AICSで開発中のメニーコア向けOS• Linuxに比べ軽量、ユーザプログラムに与える影響なし• ポスト京コンピュータにも搭載される予定。
• コンパイラ：GCC, Intel Compiler, XcalableMP• XcalableMP: 理研AICSと筑波大で共同開発中の並列プログラミング

言語• CやFortranで記述されたコードに指示文を加えることで、性能の高い並列アプリケーションを簡易に開発することができる。
• ライブラリ・アプリケーション： オープンソースソフトウェア• ppOpen-HPC, OpenFOAM, ABINIT-MP, PHASE system, FrontFlow/blue，

LAPACK, ScaLAPACK, PETSc, METIS, SuperLU etc.

2017/5/15

講習会：KNL実践

50

各種ベンチマーク• TOP 500（Linpack，HPL）• 連立一次方程式ソルバー（直接法），計算速度（FLOPS値）• 規則的な密行列：連続メモリアクセス• 計算性能• HPCG• 連立一次方程式ソルバー（反復法），計算速度（FLOPS値）• 有限要素法から得られる疎行列（ゼロが多い）• 不連続メモリアクセス• 実アプリケーションに近い• メモリアクセス性能，通信性能• Green 500• HPL（TOP500）実行時のFLOPS/W値

48th TOP500 List (November, 2016)
Site

1

Computer/Year Vendor

National Supercomputing
Center in Wuxi, China

Sunway TaihuLight , Sunway MPP,
Sunway SW26010 260C 1.45GHz,
2016 NRCPC

Tianhe-2, Intel Xeon E5-2692, TH
Express-2, Xeon Phi, 2013 NUDT
Titan
Cray XK7/NVIDIA K20x, 2012 Cray
Sequoia
BlueGene/Q, 2011 IBM
Cori, Cray XC40, Intel Xeon Phi 7250
68C 1.4GHz, Cray Aries, 2016 Cray
Oakforest-PACS, PRIMERGY CX600
Joint Center for Advanced
M1, Intel Xeon Phi Processor 7250 68C
6 High Performance
1.4GHz, Intel Omni-Path,
Computing, Japan
2016 Fujitsu
K computer, SPARC64 VIIIfx , 2011
7 RIKEN AICS, Japan
Fujitsu
Piz Daint
Swiss Natl. Supercomputer
8
Cray XC30/NVIDIA P100, 2013 Cray
Center, Switzerland
Argonne National Laboratory, Mira
9
BlueGene/Q, 2012 IBM
USA
Trinity, Cray XC40, Xeon E5-2698v3
10 DOE/NNSA/LANL/SNL, USA
16C 2.3GHz, 2016 Cray
National Supercomputing
Center in Tianjin, China
Oak Ridge National
3
Laboratory, USA
Lawrence Livermore National
4
Laboratory, USA
DOE/SC/LBNL/NERSC
5
USA
2

2017/5/15

Cores

Rmax
Rpeak
Power
(TFLOPS) (TFLOPS) (kW)10,649,600

93,015(= 93.0 PF)

125,436

15,371

3,120,000

33,863(= 33.9 PF)

54,902

17,808560,640

17,59027,1138,209

1,572,864

17,173

20,133

7,890

632,400

14,01527,881

3,939

557,056

13,55524,9142,719

705,024

10,51011,28012,660206,720

9,779

15,9881,312

786,432

8,587

10,066

3,945

301,056

8,101

11,0794,233

Rmax: Performance of 講習会：KNL実践
Linpack (TFLOPS)
Rpeak: Peak Performance (TFLOPS), Power: kW

http://www.top500.org/
51

HPCG Ranking (SC16, November, 2016)
Site
1 RIKEN AICS, Japan
2

NSCC / Guangzhou,
China

3 JCAHPC, Japan

Computer

TOP500Rank

HPCG(Pflop/s)

HPCG/
HPL (%)

705,024

10.51070.6027

5.73

Tianhe-2

3,120,000

33.86320.58001.71

557,056

13.555

6

0.3855

2.84

10,649,600

93.0151

0.3712.399

632,400

13.83250.3554

2.57

1,572,864

17.17340.3304

1.92

Titan

560,640

17.5903

0.3223

1.83

Trinity

301,0568.101

100.1826

2.25

Pleiades: SGI ICE X

243,0085.952

130.1752

2.94

Mira: IBM BlueGene/Q,

786,4328.587

90.16701.94

Oakforest-PACS

6 DOE/NNSA/LLNL, USA Sequoia

http://www.hpcg-benchmark.org/
2017/5/15

HPL Rmax(Pflop/s)

K computer

National
4 Supercomputing Center Sunway TaihuLightin Wuxi, China
DOE/SC/LBNL/NERSC
5
Cori
USA
DOE/SC/
7 Oak Ridge National
Laboratory, USA
DOE/NNSA/
8 LANL/SNL,USA
NASA / Mountain View,
9
USA
DOE/SC/
10 Argonne National
Laboratory, USA

Cores

講習会：KNL実践
52

Green 500 Ranking (SC16, November, 2016)
Site

ComputerCPU

NVIDIA DGX-1, Xeon E5-2698v4 20C
2.2GHz, Infiniband EDR, NVIDIA Tesla
P100
Swiss National
Cray XC50, Xeon E5-2690v3 12C
2 Supercomputing Piz Daint
2.6GHz, Aries interconnect , NVIDIA
Centre (CSCS)
Tesla P100
3 RIKEN ACCS
ShoubuZettaScaler-1.6 etc.
National SC
SunwaySunway MPP, Sunway SW26010
4
Center in Wuxi TaihuLight 260C 1.45GHz, Sunway
SFB/TR55 at
PRIMERGY CX1640 M1, Intel Xeon
5 Fujitsu Tech.
QPACE3Phi 7210 64C 1.3GHz, Intel OmniSolutions GmbHPath
PRIMERGY CX1640 M1, Intel Xeon
Oakforest6 JCAHPCPhi 7250 68C 1.4GHz, Intel OmniPACSPath
DOE/SC/Argonne
Cray XC40, Intel Xeon Phi 7230 64C
7
Theta
National Lab.
1.3GHz, Aries interconnect
Cray CS-Storm, Intel Xeon E5-2680v2
Stanford Research
8
XStream
10C 2.8GHz, Infiniband FDR, Nvidia
Computing Center
K80
ACCMS, Kyoto
Cray XC40, Intel Xeon Phi 7250 68C
9Camphor 2
University
1.4GHz, Aries interconnect
Jefferson Natl.
KOI Cluster, Intel Xeon Phi 7230
10
SciPhi XVI
Accel. Facility
64C 1.3GHz, Intel Omni-Path
NVIDIA
1
Corporation

2017/5/15
http://www.top500.org/

DGX
SATURNV

講習会：KNL実践

HPL
Rmax TOP500(Pflop/s Rank
)

Power
(MW)

GFLOPS/W

3.307

28

0.350

9.462

9.779

8

1.312

7.454

1.001

116

0.150

6.674

93.01

1

15.37

6.051

0.447

375

0.077

5.806

1.355

6

2.719

4.986

5.096

18

1.087

4.688

0.781

162

0.190

4.112

3.057

33

0.748

4.087

0.426

397

0.111

3.837
53

2017/5/15

講習会：KNL実践

54（理論）ピーク性能• OFPに搭載されているXeon Phi 7250のピーク性能を考える。
• コア数： 68コア
• コア当たりのAVX-512 ユニット： 2• AVX-512ユニット当たりの同時演算数（倍精度）： 8• 積和演算 (Fused Multiply Add: FMA) : 2 に換算• クロック周波数: 1.40 GHz• ノード当たりピーク性能：

68 * 2 * 8 * 2 * 1.40 = 3046.4 GFLOPS• しかし、AVX-512ユニットは実は1.40GHzでは動作しない（より低い周波数）• ピークに近い性能が得られるはずのもの（OFPでの実測値）• DGEMM (倍精度の行列積）: 2200 GFLOPS (ピーク比：72%)• HPL: 2000 GFLOPS (ピーク比： 66%)
• Top500におけるOFPの登録値はピークの54.4%• 「ピーク性能」の定義を正しく理解しておくことが重要！！

2017/5/15

講習会：KNL実践

55

FlatモードでのMCDRAMの使い方(1)(1) numactlによる方法• MCDRAMはNUMAノード1として認識されている• $ numactl –H

available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 … (省略) … 268 269 270 271
node 0 size: 98164 MB
node 0 free: 85707 MB
node 1 cpus:
node 1 size: 16384 MB
node 1 free: 15496 MB
node distances:• コード書き換えを避けたい場合には便利
node01× 配列毎の細かな使い分けはできない
0: 10 31
1: 31 10• プログラム実行時に以下を指定• $ numactl --membind 1 ./a.out(MCDRAMだけ、入りきらないとエラー）• $ numactl --preferred 1 ./a.out(MCDRAMに収まり切らない場合、DDR4も使用する）• $ numactl --interleave 1,0 ./a.out(MCDRAMとDDR4を交互に使用する）

2017/5/15

講習会：KNL実践

56

FlatモードでのMCDRAMの使い方(2)(2) 環境変数による方法：Intel MPIを使う場合• I_MPI_HBW_POLICY環境変数• export I_MPI_HBW_POLICY=hbw_bind• export I_MPI_HBW_POLICY=hbw_preferred• export I_MPI_HBW_POLICY=hbw_interleave• 事実上numactlを呼ぶのと一緒• コード書き換えを避けたい場合には便利
× 配列毎の細かな使い分けはできない
× Intel MPIのときしか有効にならない2017/5/15

講習会：KNL実践

57

FlatモードでのMCDRAMの使い方(3)(3) memkindライブラリによる方法• C• #include <hbwmalloc.h> を指定• 以下の通り、メモリ操作関連の関数名に”hbw_”をつける• malloc() => hbw_malloc()• posix_memalign() => hbw_posix_memalign()• free() => hbw_free()• コンパイル時に -lmemkind を指定• Fortran• Fastmemの属性を指定• 配列毎の細かな使い分けが可能• !dir$ attributes fastmem :: array
× 動的配列にしか適用できない• コンパイル時に -lmemkind を指定• hbw_set_policy()で切り替え• HBW_POLICY_BIND• HBW_POLICY_PREFERRED （デフォルト）• HBW_POLICY_INTERLEAVE

2017/5/15

58

講習会：KNL実践

メモリのアラインメント• AVX-512命令で512ビットデータを有効に使うためには、データがメモリ境界に揃っていることが必要• 512ビット = 64バイトの倍数のアドレスにアクセスするように• 境界以外では複数回のアクセスになる• 例：倍精度実数(double)を連続8個(=512ビット)読み出す場合
境界からずれているため、実際には複数回アクセスになる

アラインされたアクセス=効率がいい
0

1

2

3

4

64の倍数の境界

5

6

7

0

1

2

3

4

5

6

7

0

1

2

3

4

2017/5/15

講習会：KNL実践

メモリアラインメントの指定• C言語• __attribute__((aligned(64))) を指定 (64 byte = 512 bit)
• 例： double A[1024] __attribute__((aligned(64)))• 動的確保の際は posix_memalign() を使用• 上と同様の例：#include <stdlib.h>double *A;
posix_memalign(&A, 64, 1024);• Fortran• コンパイル時に -align array64byte オプションを指定

59

2017/5/15

講習会：KNL実践

OpenMPの概要

60

2017/5/15

61

講習会：KNL実践

OpenMPの対象計算機• OpenMPは共有メモリ計算機のためのプログラム言語

通信網

PE

PE

PE

PE

OpenMP
実行可能
コード

OpenMP
実行可能
コード

OpenMP
実行可能
コード

OpenMP
実行可能
コード

共有
メモリ
共有
配列
A[ ]

同時に複数のPEが共有配列にアクセス⇒並列処理で適切に制御をしないと、逐次計算の結果と一致しない2017/5/15

講習会：KNL実践

62

OpenMPとは• OpenMP (OpenMP Application Program Interface)とは、共有メモリ型並列計算機用にプログラムを並列化するための：指示文
2. ライブラリ
3. 環境変数を規格化したものです。
1.

•

•

ユーザが、並列プログラムの実行させるための指示を与えるものです。コンパイラによる自動並列化ではありません。
分散メモリ型並列化（ＭＰＩなど）に比べて、データ分散の処理の手間が無い分、実装が簡単です。

2017/5/15

講習会：KNL実践

63

OpenMPとマルチコア計算機（その１）• スレッド並列化を行うプログラミングモデル• マルチコア、メニーコア計算機に適合• 多数のスレッド実行で高い並列化効率を確保するには、

プログラミングの工夫が必要
1.
2.

メインメモリ-キャッシュ間のデータ転送能力が演算性能に比べ低い
OpenMPで並列性を抽出できないプログラムになっている（後述）• ノード間の並列化はOpenMPではできない• ノード間の並列化はMPIを用いる

2017/5/15

講習会：KNL実践

64

OpenMPとマルチコア計算機（その２）• 典型的なスレッド数• 16スレッド／ノード• T2Kオープンスパコン（AMD Quad Core Opteron(Barcelona) 、4ソケッ

ト）、FX10スーパコンピュータシステム（Sparc64 IXfx）• 32～128スレッド／ノード• HITACHI SR16000 (IBM Power7)• 32物理コア、64～128論理コア（SMT利用時）• Reedbush (Intel Xeon E5-2695 v4, Broadwell-EP)• 36コア• 60～240スレッド／ノード• Intel Xeon Phi (Intel MIC(Many Integrated Core) 、Knights Conner)• 60物理コア、120～240論理コア（HT利用時）• Oakforest-PACS (Intel MIC, Knights Landing)• 68物理コア、272論理コア利用可能• 100スレッドを超えたOpenMPによる実行形態が可能に• 相当のプログラム上の工夫が必要2017/5/15

講習会：KNL実践

OpenMPコードの書き方の原則• C言語の場合• #pragma omp

で始まるコメント行• Fortran言語の場合• !$ompで始まるコメント行

652017/5/15

講習会：KNL実践

66

OpenMPのコンパイルの仕方• 逐次コンパイラのコンパイルオプションに、OpenMP用のオプションを付ける• 例）Intel Fotran90コンパイラ

ifort -O3 -qopenmp foo.f• 例）Intel Cコンパイラ
icc -O3 -qopenmp foo.c• 注意• OpenMPの指示がないループは逐次実行• コンパイラにより、自動並列化によるスレッド並列化との併用ができる場合があるが、できない場合もある• OpenMPの指示行がある行はOpenMPによるスレッド並列化、指示がないところはコンパイラによる自動並列化• 例）Intel Fortran90コンパイラ

ifort -O3 -qparallel -qopenmp foo.f2017/5/15

講習会：KNL実践

67

OpenMPの実行可能ファイルの実行• OpenMPのプログラムをコンパイルして生成した実行可能ファイルの実行は、そのファイルを指定することで行う• スレッド数を、環境変数OMP_NUM_THREADSで指定• 例）OpenMPによる実行可能ファイルがa.outの場合$ export OMP_NUM_THREADS=16$ ./a.out
または$ env OMP_NUM_THREADS=16 ./a.out• 注意• 逐次コンパイルのプログラムと、OpenMPによるプログラムの実行速

度が、OMP_NUM_THREADS=1にしても、異なることがある（後述）• この原因は、OpenMP化による処理の増加（オーバーヘッド）• 高スレッド実行で、このオーバーヘッドによる速度低下が顕著化• プログラミングの工夫で改善可能2017/5/15

講習会：KNL実践

OpenMPの実行モデル68

2017/5/15

69

講習会：KNL実践

OpenMPの実行モデル（C言語）
OpenMP指示文
ブロックＡ#pragma omp parallel
｛
ブロックＢ
｝
ブロックＣ
※スレッド数ｐは、
環境変数
OMP_NUM_THREADS
で指定する。

ブロックＡ
スレッドの起動
スレッド０（マスタースレッド）

スレッド１

ブロックＢ

ブロックＢ

スレッドの終結

ブロックＣ

スレッドｐ-1…

ブロックＢ

2017/5/15

70

講習会：KNL実践

OpenMPの実行モデル（Fortran言語）
OpenMP指示文
ブロックＡ!$omp parallel
ブロックＢ!$omp end parallel
ブロックＣ※スレッド数ｐは、
環境変数
OMP_NUM_THREADS
で指定する。

ブロックＡ
スレッドの起動
スレッド０（マスタースレッド）

スレッド１

ブロックＢ

ブロックＢ

スレッドの終結

ブロックＣ

スレッドｐ-1…

ブロックＢ

2017/5/15

講習会：KNL実践

71

Work sharing構文• parallel指示文のように、複数のスレッドで実行する場合

において、OpenMPで並列を記載する処理（ブロックB）の部分を並列領域(parallel region)と呼ぶ。
• 並列領域を指定して、スレッド間で並列実行する処理を記述するOpenMPの構文をWork sharing構文と呼ぶ。
• Work sharing構文は、大きく分けて以下の２種がある。
1.

並列領域内で記載するもの• for構文（do構文）• sections構文• single構文 (master構文)、など

2.

parallel指示文と組み合わせるもの• parallel for 構文 (parallel do構文)• parallel sections構文、など

2017/5/15

講習会：KNL実践

代表的な指示文722017/5/15

73

講習会：KNL実践

For構文（do構文）#pragma omp parallel forfor (i=0; i<100; i++){a[i] = a[i] * b[i];}※Fortran言語の場合は!$omp parallel do～!$omp end parallel do

上位の処理
スレッドの起動

スレッド０

スレッド１

スレッド2

スレッド3

for (i=0; i<25; i++){a[i] = a[i] * b[i];}for (i=25; i<50; i++){a[i] = a[i] * b[i];}for (i=50; i<75; i++){a[i] = a[i] * b[i];}for (i=75; i<100; i++){a[i] = a[i] * b[i];}スレッドの終結※並列化をしても正しい結果になることをユーザが保障する。

下位の処理2017/5/15

講習会：KNL実践

74

For構文の指定ができない例
for (i=0; i<100; i++) { •ループ並列化指示すると、逐次と結果が異なる
a[i] = a[i] +1;（a[i-1]が更新されていない
b[i] = a[i-1]+a[i+1];
場合がある）}for (i=0; i<100; i++) {a[i] = a[ ind[i] ];}•ind[i]の内容により、
ループ並列化できるかどうか決まる•a[ind[i]]が参照時点で更新される可能性がない場
合にループ並列化できる

2017/5/15

75

講習会：KNL実践※Fortran言語の場合はSections構文#pragma omp sections{#pragma omp section
sub1();#pragma omp section
sub2();#pragma omp section
sub3();#pragma omp section
sub4();}!$omp sections～!$omp end sections
lスレッド数が３の場合

スレッド０

スレッド１

sub1();

スレッド2

sub2();

sub3();

sub4();

lスレッド数が４の場合
スレッド０
sub1();

スレッド１

スレッド2
sub2();

sub3();

スレッド3
sub4();

2017/5/15

講習会：KNL実践

76※Fortran言語の場合はCritical補助指示文!$omp critical～!$omp end critical#pragma omp critical{s = s + x;}

• ある瞬間には1つのスレッドしか実行しないことを保証
スレッド０

スレッド１

スレッド2

スレッド3

s= s+xs= s+xs= s+xs= s+x2017/5/15

77

講習会：KNL実践

Private補助指示文#pragma omp parallel for private(c)for (i=0; i<100; i++){a[i] = a[i] + c * b[i];}※変数ｃが各スレッドで別の変数を確保して実行→高速化される

上位の処理
スレッド０
for (i=0; i<25; i++){a[i] = a[i] + c0*b[i];}スレッド１for (i=25; i<50; i++){a[i] = a[i] + c1*b[i];}スレッドの起動

スレッド2

スレッド3

for (i=50; i<75; i++){a[i] = a[i] + c2*b[i];}for (i=75; i<100; i++){a[i] = a[i] + c3* b[i];}スレッドの終結

下位の処理2017/5/15

講習会：KNL実践

78

Private補助指示文の注意（Ｃ言語）#pragma omp parallel for private( j )for (i=0; i<100; i++) {for (j=0; j<100; j++) {a[ i ] = a[ i ] + amat[ i ][ j ]* b[ j ];}•ループ変数 ｊ が、各スレッドで別の変数を確保して実行される。
•private( j ) がない場合、各スレッドで 共有変数 j のカウントを勝手に行ってしまうため、100回のループ実行にならない。
→演算結果が逐次と異なり、エラーとなる。

2017/5/15

講習会：KNL実践

79

Private補助指示文の注意（Fortran言語）!$omp parallel do private( j )do i=1, 100
do j=1, 100a( i ) = a( i ) + amat( i , j ) * b( j )
enddo
enddo
!$omp end parallel do•ループ変数 ｊ が、各スレッドで別の変数を確保して実行される。
•private( j ) がない場合、各スレッドで 共有変数 j のカウントを勝手に行ってしまうため、100回のループ実行にならない。
→演算結果が逐次と異なり、エラーとなる。

2017/5/15

講習会：KNL実践

80

リダクション補助指示文（C言語）• 内積値など、スレッド並列の結果を足しこみ、１つの結果を得たい場合に利用する• 上記の足しこみはスレッド毎に非同期になされる• reduction補助指示文が無いと、ddotは単なる共有変数になるため、並列実行で逐次の結果と合わなくなくなる#pragma omp parallel for reduction(+:ddot )for (i=1; i<=100; i++) {ddot += a[ i ] * b[ i ]}ddotの場所はスカラ変数のみ記載可能（配列は記載できません）

2017/5/15

講習会：KNL実践

81

リダクション補助指示文（Fortran言語）• 内積値など、スレッド並列の結果を足しこみ、１つの結果を得たい場合に利用する• 上記の足しこみはスレッド毎に非同期になされる• reduction補助指示文が無いと、ddotは共有変数になるため、並列実行で逐次の結果と合わなくなくなる!$omp parallel do reduction(+:ddot )do i=1, 100
ddot = ddot + a(i) * b(i)enddo!$omp end parallel doddotの場所はスカラ変数のみ記載可能（配列は記載できません）

2017/5/15

講習会：KNL実践

82

リダクション補助指示文の注意• reduction補助指示文は、排他的に加算が行われるので、性能が悪い• 多くのスレッドを扱う場合、性能劣化が激しい• 以下のように、ddot用の配列を確保して逐次で加算する方が高速な場合もある（ただし、問題サイズ、ハードウェア依存）!$omp parallel do private ( i )スレッド数分のループを作成：最大ｐスレッド利用
do j=0, p-1
各スレッドでアクセスするインデックス範囲を事前に設
do i=istart( j ), iend( j )ddot_t( j ) = ddot_t( j ) + a(i) * b(i)各スレッドで用いる、ローカルなddot用のenddo
配列ddot_t()を確保し、0に初期化しておく
enddo!$omp end parallel doddot = 0.0d0
do j=0, p-1
逐次で足しこみddot = ddot + ddot_t( j )enddo2017/5/15

83

講習会：KNL実践※Fortran言語の場合はSingle構文!$omp single～!$omp end single• Single補助指示文で指定されたブロックを、
どれか１つのスレッドに割り当てる• どのスレッドに割り当てられるかは予測できない• nowait補助指示文を入れない限り、同期が入る
プログラムの開始#pragma omp parallel for｛
ブロックA#pragma omp single{ ブロックB }…
}スレッドの起動
スレッド０
スレッド１（マスタースレッド）

ブロックA

ブロックA
ブロックＢ

同期処理

スレッドｐ
…

ブロックA

2017/5/15

講習会：KNL実践

84

Master構文• 使い方は、single補助指示文と同じ• ただし、master補助指示文で指定した処理（先ほどの例の「ブロックB」の処理）は、
必ずマスタースレッドに割り当てる• 終了後の同期処理が入らない• そのため、場合により高速化される

2017/5/15

85

講習会：KNL実践

Flush構文• 物理メモリとの一貫性を取る• Flush構文で指定されている変数のみ、その場所で一貫性を取る。それ以外の共有変数の値は、メモリ上の値との一貫性は無い。
（演算結果はレジスタ上に保存されるだけ。メモリに計算結果を書き込んでいない）• つまり、flush補助指定文を書かないと、スレッド間で同時に足しこんだ
結果が、実行ごとに異なる。
• barrier補助指定文、critical補助指定文の出入口、parallel構文の出口、
for、sections、single構文の出口では、暗黙的にflushされている。
• Flushを使うと性能は悪くなる。できるだけ用いない。

#pragma omp flush (対象となる変数名の並び)省略すると、
全ての変数が対象

2017/5/15

講習会：KNL実践

86

Threadprivate構文• スレッドごとにプライベート変数にするが、スレッド内で大域アクセスできる

変数を宣言する。
• スレッドごとに異なる値をもつ大域変数の定義に向く。
• たとえば、スレッドごとに異なるループの開始値と終了値の設定#include <omp.h>…
int myid, nthreds, istart, iend;void main() {#pragma omp threadprivate(istart, iend)…
…
#pragma omp parallel private (myid,
void kernel() {nthreds, istart, iend) {int i;
nthreds = omp_num_threds();for (i=istart; i<iend; i++) {myid = omp_get_thread_num();for (j=0; j<n; j++) {istart = myid * (n/nthreads);a[ i ] = a[ i ] + amat[ i ][ j ] * b[ j ];iend = (myid+1)*(n/nthreads);}
if (myid == (nthreads-1)) {}nend = n;
スレッド毎に異なる値を持つ}}
大域変数を、parallel構文中…
kernel();で定義する}

2017/5/15

講習会：KNL実践

87

よく使うOpenMPの関数

2017/5/15

講習会：KNL実践

88

最大スレッド数取得関数• 最大スレッド数取得には、omp_get_num_threads()関数を利用する• 型はinteger (Fortran言語)、int (C言語)
l C言語の例
l Fortran90言語の例
use omp_lib
Integer nthreads#include <omp.h>
int nthreads;

nthreads = omp_get_num_threads()

nthreads = omp_get_num_threads();

2017/5/15

講習会：KNL実践

89

自スレッド番号取得関数• 自スレッド番号取得には、omp_get_thread_num()関数を利用する• 型はinteger (Fortran言語)、int (C言語)
l C言語の例
l Fortran90言語の例
use omp_lib
Integer myid#include <omp.h>
int myid;

myid = omp_get_thread_num()

myid = omp_get_thread_num();2017/5/15

講習会：KNL実践

90

時間計測関数• 時間計測には、omp_get_wtime()関数を利用する• 型はdouble precision (Fortran言語)、double (C言語)l Fortran90言語の例

l C言語の例

use omp_lib
double precision dts, dte#include <omp.h>
double dts, dte;

dts = omp_get_wtime()
対象の処理
dte = omp_get_wtime()
print *, “Elapse time [sec.] =”,dte-dts

dts = omp_get_wtime();
対象の処理
dte = omp_get_wtime();printf(“Elapse time [sec.] = %lf ¥n”,
dte-dts);

2017/5/15

講習会：KNL実践

OpenMPにおけるスケ
ジューリング91

2017/5/15

講習会：KNL実践

92

スケジューリングとは（その１）• Parallel for/do構文では、対象ループの範囲（例えば１～ｎの長さ）を、単純にスレッド個数分に分割（連続するように分割）して、並列処理をする。
ループ変数の流れ
1

スレッド0

スレッド1

スレッド2

スレッド3

スレッド4

n （反復空間）} このとき、各スレッドで担当したループに対する計

算負荷が均等でないと、スレッド実行時の台数効果
1 スレッド0
スレッド1
スレッド2
スレッド3
スレッド4 n
が悪くなる

計算負荷

2017/5/15

93

講習会：KNL実践

スケジューリングとは（その２）} 負荷分散を改善するには、割り当て間隔を短くし、かつ、循環するように割り当てればよい。
1

n

計算負荷

} 最適な、割り当て間隔（チャンクサイズとよぶ）は、計算機ハードウェアと、対象となる処理に依存する。
} 以上の割り当てを行う補助指示文が用意されている。

2017/5/15

講習会：KNL実践

94

ループスケジューリングの補助指定文（その１）• schedule (static, n)• ループ長をチャンクサイズで分割し、スレッド0番から順番に（スレッド０、スレッド１、・・・というように、ラウンドロビン方式と呼ぶ）、循環するように割り当てる。nにチャンクサイズを指定できる。
• Schedule補助指定文を記載しないときのデフォルトは、
staticで、かつチャンクサイズは、ループ長/スレッド数。
1
スレッド0

スレッド1

スレッド2

スレッド3

2017/5/15

講習会：KNL実践

95

ループスケジューリングの補助指定文（その２）• schedule(dynamic, n)• ループ長をチャンクサイズで分割し、処理が終了した

スレッドから早い者勝ちで、処理を割り当てる。nにチャンクサイズを指定できる。
1
スレッド0

スレッド1

スレッド2

スレッド3

2017/5/15

講習会：KNL実践

96

ループスケジューリングの補助指定文（その３）• schedule(guided, n)• ループ長をチャンクサイズで分割し、徐々にチャンク

サイズを小さくしながら、処理が終了したスレッドから早い者勝ちで、処理を割り当てる。nにチャンクサイ
ズを指定できる。
• チャンクサイズの指定が1の場合、残りの反復処理をスレッド数で割ったおおよその値が各チャンクのサイズになる。
• チャンクサイズは 1 に向かって指数的に小さくなる。
• チャンクサイズに 1 より大きい k を指定した場合、チャンク サイ
ズは指数的に k まで小さくなるが、最後のチャンクは k より小さくなる場合がある。
1• チャンクサイズが指定されていない場合、デフォルトは1 になる。
スレッド0
スレッド1
スレッド2
スレッド3

2017/5/15

講習会：KNL実践

97

ループスケジューリングの補助指示文の使い方
l Fortran90言語の例!$omp parallel do private( j, k ) schedule(dynamic,10)
do i=1, n
do j=indj(i), indj (i+1)-1y( i ) = amat( j ) * x( indx( j ) )
enddo
enddo
!$omp end parallel dol C言語の例#pragma omp parallel for private( j, k )schedule(dynamic,10)for (i=0; i<n; i++) {for ( j=indj(i); j<indj (i+1); j++) {y[ i ] = amat[ j ] * x[ indx[ j ]];}}2017/5/15

講習会：KNL実践

98

ループスケジューリングにおけるプログラミング上の注意• dynamic、guidedのチャンクサイズは性能に大きく影響• チャンクサイズが小さすぎると負荷バランスは良くなるが反面、処理待ちのオーバヘッドが大きくなる。
• 一方、チャンクサイズが大きすぎと負荷バランスが悪くなる半面、処理待ちのオーバヘッドが小さくなる。
• 上記の両者のトレードオフがある。
• 実行時のチャンクサイズのチューニングが必須で、チューニング
コストが増える。
• staticのみで高速実装ができる（場合がある）• dynamicなどの実行時スケジューリングは、システムのオーバーヘッドが入るが、staticはオーバーヘッドは（ほとんど）無い。
• 事前に負荷分散が均衡となるループ範囲を調べた上で、
staticスケジューリングを使うと、最も効率が良い可能性がある。
• ただし、プログラミングのコストは増大する

2017/5/15

講習会：KNL実践

99

Staticスケジューリングのみで負荷バランスを均衡化させる実装例• 疎行列-ベクトル積へ適用した例（詳細は後述）
スレッド個数文のループ!$omp parallel do private(S,J_PTR,I)（スレッドごとのループ担当
DO K=1,NUM_SMP
範囲
DO I=KBORDER(K-1)+1,KBORDER(K)を知るために必要）
事前に調べて設定しておいた、
S=0.0D0
負荷分散が均衡となる
DO J_PTR=IRP(I),IRP(I+1)-1
S=S+VAL(J_PTR)*X(ICOL(J_PTR)) スレッドごとのループ範囲
END DO（各スレッドは、連続しているが、Y(I)=S
不均衡なループ範囲を設定）
END DO
実行前に、各スレッドが担当するループ範囲について、
END DO
連続する割り当てで、かつ、それで負荷が均衡する!$omp end parallel do
問題に適用できる。
※実行時に負荷が動的に変わっていく場合は適用できない2017/5/15

講習会：KNL実践

100

OpenMPのプログラミン
グ上の注意
（全般）

2017/5/15

講習会：KNL実践

101

OpenMPによるプログラミング上の注意
点• OpenMP並列化は、

parallel構文を用いた単純なforループ並列化が主になることが多い。
• 複雑なOpenMP並列化はプログラミングコストがかかるので、OpenMPのプログラミング上の利点が失われる• parallel構文による並列化は

private補助指示文の正しい使い方を理解しないと、バグが生じる！

2017/5/15

講習会：KNL実践

102

Private補助指示文に関する注意（その１）• OpenMPでは、対象となる直近のループ変数以外は、

private変数で指定しない限り、全て共有変数になる。
• デフォルトの変数は、スレッド間で個別に確保した変数でない

l ループ変数に関する共有変数の例!$omp parallel do 宣言なしにプライベート変数として確保されるのは、
このi-ループ変数のみ
do i=1, 100
このj-ループ変数は、private宣言なしでは共有変数になる
do j=1, 100←スレッド間で早い者勝ちで更新 ←並列実行時にバグ
tmp = b(i) + c(i)a( i ) = a( i ) + tmp
enddo
この変数tmpは、private宣言なしでは共有変数になる←スレッド間で早い者勝ちで値が代入 ←並列実行時にバグ
enddo!$omp end parallel do2017/5/15

講習会：KNL実践

103

Private補助指示文に関する注意（その２）• Private補助指示文に記載する変数を減らすため、対象部分を関数化し、かつ、その関数の引数を増やすと、
関数呼び出し時間が増加し、スレッド並列化の効果を相殺することがある
l 呼び出し関数の引数が多い例!$omp parallel dodo i=1, 100
call foo(i,arg1,arg2,arg3,
arg4,arg5, ….., arg100)
enddo!$omp end parallel do

関数引数は自動的にプライベート変数になるため、private補助指示文に記載する
変数を削減できる← しかし、関数呼び出し時のオーバーヘッドが増加する← スレッド実行時においても、関数呼び出しのオーバーヘッドが無視できなくなり、台数効果が制限される※解決法：大域変数で引き渡して引数を削減2017/5/15

講習会：KNL実践

104

Private補助指示文に関する注意のまとめ• OpenMPでは、宣言せずに利用する変数は、すべて共有変数（shared variable）になる• C言語の大域変数、Fortran90言語のcommon変数、
module変数は、そのままでは共有変数になる• プライベート変数にしたい場合は、Threadprivate宣言が必要• parallel構文で関数呼び出ししている場合、その関数内でローカルに宣言している変数も、共有変数になる• そのままでは、並列処理で正常動作しない• これを防ぐには、以下のコードの変更が必要• 上記のローカル変数を引数にした関数呼び出しを作る• 上記のローカル変数を大域変数にして、Threadprivate宣言する2017/5/15

講習会：KNL実践

105

Parallel構文の入れ子に関する注意（その１）• Parallel構文は、do補助指示文で分離して記載できる• １ループが対象の場合、分離するとdo補助指示文の場所でループごとにforkするコードを生成するコンパイラ
があり、速度が低下する場合がある!$omp parallel!$omp do private(j,tmp)
do i=1, 100
do j=1, 100
tmp = b( ｊ ) + c( ｊ )a( i ) = a( i ) + tmp
enddo
enddo
!$omp end do!$omp end parallel

Parallel構文の対象が１ループ
なら parallel do
で指定!$omp parallel do private(j,tmp)
do i=1, 100
do j=1, 100
tmp = b( ｊ ) + c( ｊ )a( i ) = a( i ) + tmp
enddo
enddo
!$omp end parallel do2017/5/15

講習会：KNL実践

106

Parallel構文の入れ子に関する注意（その２）• Parallel構文は、do補助指示文で分離して記載できる• 複数ループの内側を並列化したい場合は、分離した方が高速になる• ただし、外側ループを並列化できる時はその方が性能が良い• 外側ループにデータ依存があり、並列化できない場合

do i=1, n!$omp parallel dodo j=1, n<並列化できる式>
enddo!$omp end parallel do
enddo!$omp parallel
do i=1, n!$omp dodo j=1, n<並列化できる式>
enddo!$omp end do
enddo!$omp end parallel2017/5/15

講習会：KNL実践

107

データ依存関係を壊しバグになる例• 間接参照があるインデックスに対して加算する例• 間接参照のパターン、および、スレッド実行のタイミング次第で、逐次処理と結果が一致し、正常動作だと勘違いする場合がある• 理論的には間違っている• OpenMPの共有変数は、データ一貫性の保証はしない• データ一貫性の保証には、critical補助指定文などの指定が必要

l バグになるプログラム例!$omp parallel do private( j )do i=1, n
j = indx( i )a( j ) = a( j ) + 1
enddo!$omp end parallel do!$omp parallel do private( j )do i=1, n
j = indx( i )!$omp criticala( j ) = a( j ) + 1!$omp end criticalenddo!$omp end parallel do2017/5/15

講習会：KNL実践

108

Critical補助指示文による速度低下(1/2)• 先述のように、critical補助指示文を入れないといけない場合、

特に高スレッド数での実行で性能が低下する• 高性能化するには、基本的にはアルゴリズムを変更するしかない。
• この場合、以下の３つのアプローチがある。
1.
スレッド内アクセスのみに限定し、critical補助指示文をはずす• 間接参照されるデータについて、理論的に、割り当てられた

スレッド内のデータしかアクセスしないように、アルゴリズムを変更する
2.

スレッド間アクセスを最小化• Criticalの並列領域に同時に入るスレッド数が減るように、間接参照する

データを事前に調べ、間接参照するデータの順番を変更する。
3.

スレッド間アクセス部分をループから分離し、逐次処理にする• 例）内積演算におけるリダクション補助指定文

2017/5/15

講習会：KNL実践

109

Critical補助指示文による速度低下(2/2)• 少しはマシな方法: omp atomic を使う• 高速なハードウェアによる処理が使える（はず）• ただし、単純な式 1行のみ

x = x op 式
• op: +, -, *, / , など!$omp parallel do private( j )do i=1, n
j = indx( i )!$omp atomica( j ) = a( j ) + 1
enddo!$omp end parallel do2017/5/15

講習会：KNL実践

110

OpenMPを用いた並列化の欠点（その１）• OpenMPは単純なループを並列化することに向く• 実用アプリケーションにおける複雑なループは、そのままではOpenMP化に向いていないことがある。
1. private補助指示文中に書かれる変数名の数が膨大になる• 外側ループからOpenMP並列化する場合、内部で使っている変数の数が多いことがある• private変数リストに変数を書き忘れても、コンパイラによるエラーは出ない。（並列化の責任はユーザにあるため）• 実行すると、タイミングに依存し計算結果が逐次と異なる。
どこが間違っているかわからないので、デバックが大変になる。
• 解決策：コンパイラによっては、最適化情報を出力することができる。その情報から、ちゃんとprivate化されているか確認する。

2017/5/15

講習会：KNL実践

111

OpenMPを用いた並列化の欠点（その２）
高スレッド実行時に性能が出ない場合のチューニングが困難
1. 近年のハードウェアはメモリアクセスの性能が相対的に低い
2. ループそのものにそれほど並列性がない（ループ長が短い）• 解決するには、アルゴリズムの変更、実装の変更、が必要になり、OpenMPの利点である容易なプログラミングを損なう
3. 複雑なスレッドプログラミングには向かない• 単純な数値計算のカーネルループを、parallel for構文で記載する方針で仕様が作られている• 複雑な処理は、task文、またはPthreadなどのnativeなスレッ
ドAPI、またはTBB, Cilkなどの他の並列化手法で書くほうが
やりやすい
2.

2017/5/15

講習会：KNL実践KNLにおけるOpenMP
実行の注意点112

2017/5/15

113

講習会：KNL実践

KNL(OFP)におけるHyperThreading• 物理コア: 68コア
• HyperThreading(HT)有効: 1コアあたり 4 HT=> 合計 272スレッド実行可能• AVX-512ユニットはあくまでもコアあたり2個しかない• 2つのAVX-512ユニットを埋め尽くせれば 1 HTでいいはず• AVX-512ユニット1基しか使えていなければ 2 HT使った方がいい• メモリアクセスを隠蔽する必要があれば
3~4 HTがいい場合も
2 VPU
Core

2 VPU
1MB
L2

1タイル=2コアCore2017/5/15

114

講習会：KNL実践

OFPにおけるスレッド割付け• メニーコア => OS割り込み処理などによるジッタの影響を受けやすい• 遅いコアが一人いると全員が影響を受ける• 特にタイマ割り込みは 1ms毎にやってくる• OFPでは、コア0のみタイマ割り込みを受け取るように設定（今後変わる可能性もあり）• コア0と、タイル内でL2キャッシュを直接共有しているコア1も影響を受ける• HTコアも当然影響を受ける• コア番号 0,1, 68,69, 136,137, 204, 205

は実行から外した方がいい(場合が多い)• 数%以上性能が改善する• 具体的な指定方法は後述

2 VPU
Core0

2 VPU
1MB
L2

Core1

1タイル=2コア2017/5/15

115

講習会：KNL実践

スレッド並列数と性能への影響(1)Xeon Phiは、Xeonなど通常のマルチコアCPUに比べて• コアのクロックが遅い• ReedbushのBroadwell (2.3GHz)に比べて 1.6倍程度• メモリアクセスレイテンシも大きい• チップ内ネットワークが複雑
25ÞOpenMPの指示文に対する• 右図：各指示文のオーバ

ヘッド (EPCC syncbench)• 8コアから16コアで大きな影響があるように見える• 2コアは同一タイル、• 4~64コアは物理コアのみ、• 128~256コアはHT使用

Overhead (usec)

オーバヘッドが大きくなる

20

PARALLELFOR
PARALLEL FOR

15

BARRIERSINGLE

10

REDUCTION

5
0
2

4

8

16

32

# Core

64

128

256

2017/5/15

116

講習会：KNL実践

スレッド並列数と性能への影響(2)• 右図：各指示文(Atomic系)のオーバヘッド (EPCC syncbench)• Xeon Broadwell 32コアでは Atomic: 0.1us以下
Critical, Lock/Unlock: 0.4us以下=> メモリアクセスレイテンシの影響• Parallel for/doなど、様々な指示文にも暗にバリア処理は含まれている• 最大限大きくParallel regionを取る• 毎回Parallel for/doするのではなく、Parallel の中でfor/doだけを繰り返す• MPI+OpenMPハイブリッド実行により、スレッド並列数を下げる• アプリケーションに依存する• あとで詳しく

CRITICAL

2.5

LOCK/UNLOCK
Overhead (usec)

対策• なるべくAtomic処理やバリア処理を減らす

3

2

ATOMIC

1.5
1
0.5
0
2

4

8

16
# Core

32

64

128

256

2017/5/15

講習会：KNL実践

KNL単体(1ノード)に
おける実行

117

2017/5/15

講習会：KNL実践

118

コンパイル
Intel Compiler 2017 update 2を想定 (OFPのデフォルト)• Cコンパイラ: icc• Fortranコンパイラ: ifort
必須オプション
• -xMIC-AVX512• KNL向けコード生成• -O3• 最適化レベル• -qopenmp• OpenMP有効• -align array64byte• (Fortranのみ）配列を64byteにアライン（前述）

試した方がいい• -qopt-streaming-stores=
always / never / auto
• always: キャッシュに載せない命令を使う、キャッシュの生存時間が短い場合に有効• neverはその逆• デフォルトはauto• ループの各配列ごとにも制御可能(以下はalways相当)• #pragma vector nontemporal (inC/C++)• !DIR$ vector nontemporal (in F)2017/5/15

講習会：KNL実践

119

実行時の指定• 68コアのうち、64コアを使うことを想定• ジッタを防ぐための設定、コア 0,1, 68,69, 136,137, 204, 205を排除1. 1タイルあたり1コアのみ、32コア使用• キャッシュ利用効率を重視する場合
2. 1コア1HT、64コア使用
3. 1コア2HT、128コア使用
4. 1コア3HT、192コア使用
5. 1コア4HT、256コア使用

2017/5/15

講習会：KNL実践

120

32コア使用する場合• タイルあたり1スレッド• 明示的にプロセス割付を指定する
export OMP_NUM_THREADS=32
export KMP_AFFINITY=proclist=[2,4,6,8,10,12,14,16,18,20,
22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,
56,58,60,62,64,66],explicit,verbose
2 VPU

0

Core

2 VPU

2

Core

1MB
L2

1MB
L2

2 VPU

2 VPU

Core

Core

2 VPU

2 VPU

Core

Core

1

3

1MB
L2

1MB
L2

2 VPU
Core

2 VPU
Core

・・・

・・・

2017/5/15

講習会：KNL実践

121

64コア使用する場合• コアあたり1スレッド• KMP_HW_SUBSET環境変数が使える• 物理コア数c@オフセット,コアあたりスレッド数t• 64c@2,1t: 64コア、コア番号2から使用、コアあたり1スレッド

export OMP_NUM_THREADS=64
export KMP_HW_SUBSET=64c@2,1t
export KMP_AFFINITY=scatter,verbose
2 VPU

0

Core

2 VPU

4

Core

1MB
L2

1MB
L2

2 VPU

2 VPU

Core

1

Core

2 VPU

2 VPU

5

Core

Core

2

6

1MB
L2

1MB
L2

2 VPU

3

Core

2 VPU

7

Core

・・・

・・・

2017/5/15

講習会：KNL実践

122

128コア使用する場合• コアあたり2スレッド• KMP_HW_SUBSET環境変数：64c@2,2t• KMP_AFFINITYにcompactを指定• scatterにすると、同一コアにスレッド0と64、スレッド1と65…のようになり、キャッシュが非効率

export OMP_NUM_THREADS=128
export KMP_HW_SUBSET=64c@2,2t
export KMP_AFFINITY=compact,verbose
2 VPU

01

Core

2 VPU
Core

89

1MB
L2

1MB
L2

2 VPU

2 VPU

Core

23

4Core5

2 VPU

2 VPU

10Core11

12 13
Core

1MB
L2

1MB
L2

2 VPU

67

Core

2 VPU

14 15
Core

・・・

・・・

2017/5/15

講習会：KNL実践

123

192, 256コア使用する場合
192コア• コアあたり3スレッド

256コア• コアあたり4スレッド

export OMP_NUM_THREADS=192
export KMP_HW_SUBSET=64c@2,3t
export KMP_AFFINITY=compact,
verboseexport OMP_NUM_THREADS=256
export KMP_HW_SUBSET=64c@2,
4t
export KMP_AFFINITY=compact,
verbose2017/5/15

講習会：KNL実践

124

コア割り当ての確認
最初は必ず確認すること（想定通りになっていなくて悲しい思いをする）• KMP_AFFINITY環境変数にverboseを指定• 標準エラー出力（e+数字のファイル）にレポート出力• 見るべきは以下のような出力（最後の方）• 32コア実行の例: スレッド0がコア2, スレッド1がコア4, スレッド2がコア6…に割り当て
OMP: Info #242: KMP_AFFINITY: pid X tid XX thread 0 bound to OS proc set {2}OMP: Info #242: KMP_AFFINITY: pid X tid XY thread 1 bound to OS proc set {4}OMP: Info #242: KMP_AFFINITY: pid X tid XZ thread 2 bound to OS proc set {6}…

2017/5/15

講習会：KNL実践

125

ベクトル化、スレッド化、実行効率の確認• コンパイル時に最適化レポートを確認• -qopt-report=5• ファイル名.optrpt を確認• ツールを利用する• Intel Advisor XE• ベクトル化、スレッド並列化のアドバイス• Intel VTune XE• プロファイリング

2017/5/15

演習

講習会：KNL実践

126

2017/5/15

講習会：KNL実践

127

KNL/OFPにおける
MPI+OpenMPハイブリッド

2017/5/15

講習会：KNL実践

128

MPI+OpenMPハイブリッド実行の意義• MPIランク数の増加に伴い、消費メモリもオーバヘッドも増加• 通常は以下のような組み合わせが良いとされて来た
ノード内：OpenMP
ノード間：MPI• またReedbushのように2ソケットでNUMAを構成していればソケット内: OpenMP
ソケット間+ノード間: MPI• フラットMPIも可能だがよろしくない
メニーコアクラスタではそう単純でもない2017/5/15

講習会：KNL実践

129

MPIの特徴• メッセージパッシング用のライブラリ規格の１つ• メッセージパッシングのモデルである• コンパイラの規格、特定のソフトウエアやライブラリを指すものではない！

• 分散メモリ型並列計算機で並列実行に向く• 大規模計算が可能• １プロセッサにおけるメモリサイズやファイルサイズの制約を打破可能• プロセッサ台数の多い並列システム（Massively Parallel Processing(MPP)システム）を用いる実行に向く• １プロセッサ換算で膨大な実行時間の計算を、短時間で処理可能• 移植が容易• API（Application Programming Interface）の標準化• スケーラビリティ、性能が高い• 通信処理をユーザが記述することによるアルゴリズムの最適化が可能• プログラミングが難しい（敷居が高い）2017/5/15

講習会：KNL実践

130

MPIの経緯（これまで）• MPIフォーラム（http://www.mpi-forum.org/）が仕様策

定• 1994年5月 1.0版（MPI-1）• 1995年6月 1.1版
• 1997年7月 1.2版、 および 2.0版（MPI-2）• 2008年5月 1.3版、 2008年6月 2.1版
• 2009年9月 2.2版
• 日本語版 http://www.pccluster.org/ja/mpi.html• MPI-2 では、以下を強化：• 並列I/O• C++、Fortran 90用インターフェース• 動的プロセス生成/消滅• 主に、並列探索処理などの用途

2017/5/15

講習会：KNL実践131

MPIの経緯 MPI-3.1• MPI-3.0 2012年9月• MPI-3.1 2015年6月• 以下のページで現状・ドキュメントを公開中• http://mpi-forum.org/docs/docs.html• http://meetings.mpi-forum.org• http://meetings.mpi-forum.org/mpi31-impl-status-Nov15.pdf• 注目すべき機能• ノン・ブロッキング集団通信機能（MPI_IALLREDUCE、など）• 高性能な片方向通信（RMA、Remote Memory
Access)• Fortran2008 対応、など

2017/5/15

講習会：KNL実践132

MPIの経緯 MPI-4.0策定中• 以下のページで経緯・ドキュメントを公開• http://meetings.mpi-

forum.org/MPI_4.0_main_page.php• 検討されている機能• ハイブリッドプログラミングへの対応• MPIアプリケーションの耐故障性（Fault Tolerance,
FT）• いくつかのアイデアを検討中• Active Messages (メッセージ通信のプロトコル)••••

計算と通信のオーバラップ
最低限の同期を用いた非同期通信
低いオーバーヘッド、パイプライン転送
バッファリングなしで、インタラプトハンドラで動く• Stream Messaging• 新プロファイル・インターフェース2017/5/15

講習会：KNL実践

MPIの実装• MPICH（エム・ピッチ）• 米国アルゴンヌ国立研究所が開発• MVAPICH (エムヴァピッチ)• 米国オハイオ州立大学で開発、MPICHをベース• InfiniBand向けの優れた実装• OpenMPI• オープンソース• ベンダMPI• 大抵、上のどれかがベースになっている
例: 富士通「京」、FX10用のMPI: Open-MPIベース
Intel MPI: MPICH、MVAPICHベース• 注意点:メーカ独自機能拡張がなされていることがある133

2017/5/15

講習会：KNL実践

MPIによる通信• 郵便物の郵送に同じ• 郵送に必要な情報：
1. 自分の住所、送り先の住所
2. 中に入っているものはどこにあるか
3. 中に入っているものの分類
4. 中に入っているものの量
5. （荷物を複数同時に送る場合の）認識方法（タグ）• MPIでは：
1. 自分の認識ID、および、送り先の認識ID
2. データ格納先のアドレス
3. データ型
4. データ量
5. タグ番号134

2017/5/15

講習会：KNL実践

MPI関数• システム関数• MPI_Init； MPI_Comm_rank； MPI_Comm_size； MPI_Finalize；• １対１通信関数• ブロッキング型• MPI_Send；

MPI_Recv；• ノンブロッキング型• MPI_Isend； MPI_Irecv；• １対全通信関数• MPI_Bcast• 集団通信関数• MPI_Reduce； MPI_Allreduce； MPI_Barrier；• 時間計測関数• MPI_Wtime

135

2017/5/15

講習会：KNL実践

136

コミュニケータ• MPI_COMM_WORLDは、コミュニケータとよばれる概念を保存する変数• コミュニケータは、操作を行う対象のプロセッサ群を定める• 初期状態では、０番～numprocs –１番までのプロセッサが、１つのコミュニケータに割り当てられる• この名前が、“MPI_COMM_WORLD”• プロセッサ群を分割したい場合、MPI_Comm_split 関数を利用• メッセージを、一部のプロセッサ群に放送するときに利用• “マルチキャスト”で利用2017/5/15

講習会：KNL実践

137

略語とMPI用語• MPIは「プロセス」間の通信を行います。プロセスは（普通は）「プロセッサ」（もしくは、コア）に一対一で割り当てられます。
• 今後、「MPIプロセス」と書くのは長いので、ここではPE（Processer Elementsの略）と書きます。
• ただし用語として「PE」は現在はあまり使われていません。

• ランク（Rank）• 各「MPIプロセス」の「識別番号」のこと。
• 通常MPIでは、MPI_Comm_rank関数で設定される変数（サンプルプログラムではmyid）に、０～全PE数－１ の数値が入る• 世の中の全MPIプロセス数を知るには、MPI_Comm_size関数を使う。
（サンプルプログラムでは、numprocs に、この数値が入る）2017/5/15

講習会：KNL実践

基本的なMPI関数
送信、受信のためのインタフェース

138

2017/5/15

講習会：KNL実践

139

C言語インターフェースとFortranインターフェースの違い• Ｃ版は、

整数変数ierr が戻り値
ierr = MPI_Xxxx(….);• Fortran版は、最後に整数変数ierrが引数
call MPI_XXXX(…., ierr)• システム用配列の確保の仕方• Ｃ言語

MPI_Status istatus;• Fortran言語
integer istatus(MPI_STATUS_SIZE)2017/5/15

講習会：KNL実践

140

C言語インターフェースとFortranインターフェースの違い• MPIにおける、データ型の指定• C言語
MPI_CHAR (文字型) 、 MPI_INT (整数型)、
MPI_FLOAT (実数型)、MPI_DOUBLE(倍精度実数型)• Fortran言語
MPI_CHARACTER (文字型) 、MPI_INTEGER(整数型)、MPI_REAL (実数型)、
MPI_DOUBLE_PRECISION(倍精度実数型) 、
MPI_COMPLEX(複素数型)• 以降は、Ｃ言語インタフェースで説明する

2017/5/15

講習会：KNL実践

141

基礎的なMPI関数―MPI_Recv （1/2）• ierr = MPI_Recv(recvbuf, icount, idatatype, isource,

itag, icomm, istatus);• recvbuf :受信領域の先頭番地を指定する。
• icount : 整数型。受信領域のデータ要素数を指定する。
• idatatype : 整数型。受信領域のデータの型を指定する。
• MPI_CHAR (文字型) 、MPI_INT (整数型)、

MPI_FLOAT (実数型)、

MPI_DOUBLE(倍精度実数型)• isource :整数型。受信したいメッセージを送信するPEのランクを指定する。

• 任意のPEから受信したいときは、MPI_ANY_SOURCE を指定する。

2017/5/15

講習会：KNL実践

142

基礎的なMPI関数―MPI_Recv （2/2）• itag : 整数型。受信したいメッセージに付いているタグの値を指定。
• 任意のタグ値のメッセージを受信したいときは、MPI_ANY_TAG を指定。
• icomm : 整数型。PE集団を認識する番号であるコミュニケータ

を指定。
• 通常ではMPI_COMM_WORLD を指定すればよい。

• istatus : MPI_Status型（整数型の配列）。受信状況に関する情報が入る。かならず専用の型宣言をした配列を確保すること。
• 要素数がMPI_STATUS_SIZEの整数配列が宣言される。
• 受信したメッセージの送信元のランクが istatus[MPI_SOURCE]、

タグが istatus[MPI_TAG] に代入される。
• C言語： MPI_Status istatus;• Fortran言語： integer istatus(MPI_STATUS_SIZE)• ierr(戻り値) : 整数型。エラーコードが入る。

2017/5/15

講習会：KNL実践

143

基礎的なMPI関数―MPI_Send• ierr = MPI_Send(sendbuf, icount, idatatype, idest,

itag, icomm);• sendbuf :送信領域の先頭番地を指定• icount : 整数型。送信領域のデータ要素数を指定• idatatype : 整数型。送信領域のデータの型を指定• idest : 整数型。送信したいPEのicomm内でのランクを指定• itag : 整数型。受信したいメッセージに付けられたタグの値を指定• icomm : 整数型。プロセッサー集団を認識する番号である
コミュニケータを指定• ierr (戻り値) : 整数型。エラーコードが入る。

2017/5/15

講習会：KNL実践

144

Send－Recvの概念（１対１通信）
PE0

PE１

PE２

PE３

MPI_Send

完了までプログ
ラム実行中断！

再開

MPI_Recv

2017/5/15

講習会：KNL実践

基礎的なMPI関数―MPI_Bcast• ierr = MPI_Bcast(sendbuf, icount, idatatype,iroot, icomm);• sendbuf :送信および受信領域の先頭番地を指定する。
• icount : 整数型。送信領域のデータ要素数を指定する。
• idatatype : 整数型。送信領域のデータの型を指定する。
• iroot : 整数型。送信したいメッセージがあるPEの番号を指定する。全PEで同じ値を指定する必要がある。
• icomm : 整数型。PE集団を認識する番号である
コミュニケータを指定する。
• ierr (戻り値) : 整数型。エラーコードが入る。

145

2017/5/15

146

講習会：KNL実践

MPI_Bcastの概念（集団通信）
PE0

PE１

MPI_Bcast()

MPI_Bcast()

iroot

PE２

PE３

MPI_Bcast()

MPI_Bcast()

全PEが同じように関数を呼ぶこと!!

2017/5/15

講習会：KNL実践

147

リダクション演算• ＜操作＞によって＜次元＞を減少（リダクション）させる処理
• 例：

内積演算
ベクトル（ｎ次元空間）
間）→

スカラ（１次元空• リダクション演算は、通信と計算を必要とす

る• 集団通信演算（collective communication

operation）と呼ばれる• 演算結果の持ち方の違いで、２種のインタフェースが存在する

2017/5/15

148

講習会：KNL実践

リダクション演算• 演算結果に対する所有PEの違い• MPI_Reduce関数• リダクション演算の結果を、ある一つのPEに所有させる
PE0
PE0
PE1

操作
操作

PE2

PE0

• MPI_Allreduce関数• リダクション演算の結果を、全てのPEに所有させる
PE0
PE1

PE0

操作
PE2

PE1

PE2

2017/5/15

講習会：KNL実践

149

基礎的なMPI関数―MPI_Reduce• ierr = MPI_Reduce(sendbuf, recvbuf, icount,

idatatype, iop, iroot, icomm);• sendbuf : 送信領域の先頭番地を指定する。
• recvbuf : 受信領域の先頭番地を指定する。iroot で指定したPEのみで書き込みがなされる。
送信領域と受信領域は、同一であってはならない。
すなわち、異なる配列を確保しなくてはならない。
• icount : 整数型。送信領域のデータ要素数を指定する。
• idatatype : 整数型。送信領域のデータの型を指定する。

• （Fortran）＜最小／最大値と位置＞を返す演算を指定する場合は、MPI_2INTEGER(整数型)、
MPI_2REAL(単精度型)、MPI_2DOUBLE_PRECISION(倍精度型) 、を指定する。

2017/5/15

講習会：KNL実践

150

基礎的なMPI関数―MPI_Reduce• iop :
整数型。演算の種類を指定する。
• MPI_SUM (総和)、 MPI_PROD (積)、 MPI_MAX (最大)、MPI_MIN (最小)、 MPI_MAXLOC (最大とその位置)、 MPI_MINLOC (最小とその位置) など。
• iroot :整数型。結果を受け取るPEのicomm 内
でのランクを指定する。全てのicomm 内のPEで同じ値を指定する必要がある。
• icomm :整数型。PE集団を認識する番号であるコミュニケータを指定する。
• ierr : 整数型。 エラーコードが入る。

2017/5/15

講習会：KNL実践

151

MPI_Reduceの概念（集団通信）
PE0

PE１

MPI_Reduce()

MPI_Reduce()

PE２

PE３

MPI_Reduce()

MPI_Reduce()

データ３

データ４

iroot
データ１

データ２

iop（指定された演算）2017/5/15

152

講習会：KNL実践

MPI_Reduceによる２リスト処理例（MPI_2DOUBLE_PRECISION と MPI_MAXLOC）

PE0

PE１

MPI_Reduce()

MPI_Reduce()

PE２

PE３

MPI_Reduce()

MPI_Reduce()

iroot
3.1

4.1

5.9

2.6

2.0

5.0

9.0

13.0

MPI_MAXLOC
5.99.0

LU分解の枢軸選択処理2017/5/15

講習会：KNL実践

153

基礎的なMPI関数―MPI_Allreduce• ierr = MPI_Allreduce(sendbuf, recvbuf, icount,

idatatype, iop, icomm);• sendbuf : 送信領域の先頭番地を指定する。
• recvbuf : 受信領域の先頭番地を指定する。iroot で指定したPEのみで書き込みがなされる。
送信領域と受信領域は、同一であってはならない。
すなわち、異なる配列を確保しなくてはならない。
• icount : 整数型。送信領域のデータ要素数を指定する。
• idatatype : 整数型。送信領域のデータの型を指定する。
• 最小値や最大値と位置を返す演算を指定する場合は、MPI_2INT(整数型)、MPI_2FLOAT (単精度型)、
MPI_2DOUBLE(倍精度型) を指定する。

2017/5/15

講習会：KNL実践

154

基礎的なMPI関数―MPI_Allreduce• iop :

整数型。演算の種類を指定する。
• MPI_SUM (総和)、 MPI_PROD (積)、MPI_MAX (最大)、MPI_MIN (最小)、MPI_MAXLOC (最大と位置)、 MPI_MINLOC(最小と位置) など。
• icomm :整数型。PE集団を認識する番号であるコミュニケータを指定する。
• ierr : 整数型。 エラーコードが入る。

2017/5/15

講習会：KNL実践

155

MPI_Allreduceの概念（集団通信）
PE0

PE１

PE２

PE３

MPI_Allreduce()

MPI_Allreduce()

MPI_Allreduce()

MPI_Allreduce()

データ０

データ１

データ２

データ３

iop（指定された演算）
演算済みデータの放送2017/5/15

講習会：KNL実践

156

リダクション演算• 性能について• リダクション演算は、１対１通信に比べ遅い• プログラム中で多用すべきでない！
• MPI_Allreduce は MPI_Reduce に比べ遅い
• MPI_Allreduce は、放送処理が入る。
• なるべく、MPI_Reduce を使う。

2017/5/15

講習会：KNL実践

157

基礎的なMPI関数―MPI_Gather• ierr = MPI_Gather (sendbuf, isendcount, isendtype,recvbuf, irecvcount, irecvtype, iroot, icomm);• sendbuf :送信領域の先頭番地を指定する。
• isendcount:
整数型。送信領域のデータ要素数を指定する。
• isendtype :整数型。送信領域のデータの型を指定する。
• recvbuf :受信領域の先頭番地を指定する。iroot で指定したPEのみで書き込みがなされる。
• なお原則として、送信領域と受信領域は、同一であってはならない。

すなわち、異なる配列を確保しなくてはならない。
• irecvcount:

整数型。受信領域のデータ要素数を指定する。

• この要素数は、１PE当たりの送信データ数を指定すること。
• MPI_Gather 関数では各PEで異なる数のデータを収集することはできないので、同じ値を指定すること。

2017/5/15

講習会：KNL実践

158

基礎的なMPI関数―MPI_Gather• irecvtype :整数型。受信領域のデータ型を指定する。
• iroot :整数型。収集データを受け取るPEのicomm 内でのランクを指定する。
• 全てのicomm 内のPEで同じ値を指定する必要がある。
• icomm :整数型。PE集団を認識する番号である
コミュニケータを指定する。
• ierr :整数型。エラーコードが入る。

2017/5/15

159

講習会：KNL実践

MPI_Gatherの概念（集団通信）
PE0

PE１

PE２

PE３

MPI_Gather()

MPI_Gather()

MPI_Gather()

MPI_Gather()

データC

データD

iroot
データA

データB

収集処理
データA
データB
データC
データD

2017/5/15

講習会：KNL実践

160

基礎的なMPI関数―MPI_Scatter• ierr = MPI_Scatter ( sendbuf, isendcount, isendtype,recvbuf, irecvcount, irecvtype, iroot, icomm);• sendbuf :送信領域の先頭番地を指定する。
• isendcount:
整数型。送信領域のデータ要素数を指定する。
• この要素数は、１PE当たりに送られる送信データ数を指定すること。
• MPI_Scatter 関数では各PEで異なる数のデータを分散することはできないので、同じ値を指定すること 。
• isendtype :整数型。送信領域のデータの型を指定する。
iroot で指定したPEのみ有効となる。
• recvbuf :受信領域の先頭番地を指定する。
• なお原則として、送信領域と受信領域は、同一であってはならない。

すなわち、異なる配列を確保しなくてはならない。
• irecvcount:

整数型。受信領域のデータ要素数を指定する。

2017/5/15

講習会：KNL実践

161

基礎的なMPI関数―MPI_Scatter• irecvtype :整数型。受信領域のデータ型を指定する。
• iroot :整数型。収集データを受け取るPEのicomm 内でのランクを指定する。
• 全てのicomm 内のPEで同じ値を指定する必要がある。
• icomm :整数型。PE集団を認識する番号である
コミュニケータを指定する。
• ierr :整数型。エラーコードが入る。

2017/5/15

162

講習会：KNL実践

MPI_Scatterの概念（集団通信）
PE0

PE１

PE２

PE３

MPI_Scatter()

MPI_Scatter()

MPI_Scatter()

MPI_Scatter()

iroot
データA
データB
データC
データD

分配処理
データA

データB

データC

データD

2017/5/15

163

講習会：KNL実践

MPI_Scatterの概念（集団通信）
PE0

PE１

PE２

PE３

MPI_Scatter()

MPI_Scatter()

MPI_Scatter()

MPI_Scatter()

iroot
データA
データB
データC
データD

分配処理
データA

データB

データC

データD

2017/5/15

講習会：KNL実践

164

ブロッキング、ノンブロッキング
1.

ブロッキング•

送信／受信側のバッファ領域にメッセージが格納され、受信／送信側のバッファ領域が自由にアクセス・上書きできるまで、呼び出しが戻らない••

バッファ領域上のデータの一貫性を保障
MPI_Send, MPI_Bcastなど

2.

ノンブロッキング• 送信／受信側のバッファ領域のデータを保障せずすぐに呼び出しが戻る• バッファ領域上のデータの一貫性を保障せず• 一貫性の保証はユーザの責任2017/5/15

165

講習会：KNL実践

ブロッキング通信で効率の悪い例• プロセス0が必要なデータを持っている場合

連続するsendで、効率の悪い受信待ち時間が多発

プロセス0

計算

プロセス1

計算

プロセス２

計算

プロセス３

計算

…

send

受信待

send

recv

受信待

send

受信待

計算
recv

計算

次の反復での同期待ち

計算
recv

…

次の反復での同期待ち

計算

次の反復での
同期待ち

…
次の
反復での
同期点

2017/5/15

講習会：KNL実践

166

ノンブロッキング通信関数• ierr = MPI_Isend(sendbuf, icount, datatype,

idest, itag, icomm, irequest);• sendbuf : 送信領域の先頭番地を指定する• icount : 整数型。送信領域のデータ要素数を指定する• datatype : 整数型。送信領域のデータの型を指定する• idest : 整数型。送信したいPEのicomm 内でのランクを指定する• itag : 整数型。受信したいメッセージに付けられたタグの値を指定する2017/5/15

講習会：KNL実践

167

ノンブロッキング通信関数• icomm : 整数型。PE集団を認識する番号であるコミュニケータを指定する。
• 通常ではMPI_COMM_WORLD を指定すればよい。
• irequest : MPI_Request型（整数型の配列）。
送信を要求したメッセージにつけられた識別子が戻る。
• ierr : 整数型。エラーコードが入る。

2017/5/15

講習会：KNL実践

168

同期待ち関数• ierr = MPI_Wait(irequest, istatus);• irequest : MPI_Request型（整数型配列）。

送信を要求したメッセージにつけられた識別子。
• istatus :MPI_Status型（整数型配列）。
受信状況に関する情報が入る。
• 要素数がMPI_STATUS_SIZEの整数配列を宣言して指定する。
• 受信したメッセージの送信元のランクがistatus[MPI_SOURCE] 、タグがistatus[MPI_TAG] に代入される。
• 送信データを変更する前・受信データを読み出す前には必ず呼ぶこと2017/5/15

169

講習会：KNL実践

ノン・ブロッキング通信による改善• プロセス0が必要なデータを持っている場合
連続するsendにおける受信待ち時間を
ノン・ブロッキング通信で削減

プロセス0

計算

send send

プロセス1

計算

recv

プロセス２

計算

プロセス３

計算

…

send

…

計算
recv

計算

受信待

次の反復で
の同期待ち

次の反復での同期待ち

計算
recv

…

受信待ちを、MPI_Waitで計算の後に行うように変更

次の反復での同期待ち

計算
次の
反復での
同期点

2017/5/15

講習会：KNL実践

170

注意点• 以下のように解釈してください：• MPI_Send関数• 関数中にMPI_Wait関数が入っている；• MPI_Isend関数• 関数中にMPI_Wait関数が入っていない；• かつ、すぐにユーザプログラムに戻る；2017/5/15

講習会：KNL実践

171

参考文献
MPI並列プログラミング、P.パチェコ 著 ／ 秋葉 博 訳
2. 並列プログラミング虎の巻MPI版、青山幸也 著、
理化学研究所情報基盤センタ（ http://accc.riken.jp/HPC/training/text.html ）3. Message Passing Interface Forum（ http://www.mpi-forum.org/ ）4. MPI-Jメーリングリスト（ http://phase.hpcc.jp/phase/mpi-j/ml/ ）1.

5.

並列コンピュータ工学、富田眞治著、昭晃堂（１９９６）

2017/5/15

講習会：KNL実践

172

時間計測方法（C言語）
double t0, t1, t2, t_w;..
ierr = MPI_Barrier(MPI_COMM_WORLD);
t1 = MPI_Wtime();

バリア同期後時間を習得し保存＜ここに測定したいプログラムを書く＞
t2 = MPI_Wtime();t0 = t2 - t1;
ierr = MPI_Reduce(&t0, &t_w, 1,
MPI_DOUBLE,MPI_MAX, 0,
MPI_COMM_WORLD);

各プロセッサーで、ｔ0の値は異なる。
この場合は、最も遅いものの値をプロセッサ０番が受け取る

2017/5/15

173

講習会：KNL実践

時間計測方法（Fortran言語）
double precision t0, t1, t2, t_w
double precision MPI_WTIME..
call MPI_BARRIER(MPI_COMM_WORLD, ierr)
t1 = MPI_WTIME(ierr)

バリア同期後時間を習得し保存＜ここに測定したいプログラムを書く＞
t2 = MPI_WTIME(ierr)
t0 = t2 - t1
call MPI_REDUCE(t0, t_w, 1,&
MPI_DOUBLE_PRECISION,&MPI_MAX, 0, MPI_COMM_WORLD, ierr)

各プロセッサーで、ｔ0の値は異なる。
この場合は、最も遅いものの値をプロセッサ０番が受け取る2017/5/15

講習会：KNL実践

174

Omni Pathに関するヒント
プロトコルスタック選択• I_MPI_FABRICS=ノード
内:ノード間• shm: 共有メモリ（ノード内のみ選択可）• tmi: Omni Pathのおすすめ• ofi: 将来の標準• デフォルトでは shm:tmi

だが、経験上集団通信は
tmi:tmi にした方が高速

試した方がいい• HFI_NO_CPUAFFINITY=1• 差が出る場合と出ない場合がある？
• ノード内複数プロセス実行

時などは指定した方がいいかも2017/5/15

175

講習会：KNL実践

MPI+OpenMPハイブリッド実行に際して• MPI関数を、マルチスレッド環境で実行する際は注意が必要• 3つのモード: Master only, Funneled, Multiple• Multipleでは、集団通信は単純には実行できない、あまりスケールしない• Master onlyではParallelリージョンから出なければいけない• 特に意識しないのであればFunneledで使うのがよい

Master only

Funneled

Multiple#pragma omp parallel{....
}
MPI_Send( ... );#pragma omp parallel
{
....
}

#pragma omp parallel{....
#pragma omp master
MPI_Send( ... );....
}#pragma omp parallel{....
MPI_Send( ... );....
}Master onlyと似ているがparallel節を閉じなくていい

本当にマルチスレッド
だが、1対1通信しかできない

2017/5/15

講習会：KNL実践

176

マルチスレッドMPIの初期化• MPI_Init()の代わりに、MPI_Init_thread()を使用• C言語:

int provided;
MPI_Init_thread(&argc,&argv,MPI_THREAD_FUNNELED,&provided);• Fortran

integer provided
call MPI_Init_thread(MPI_THREAD_FUNNELED,
provided, ierr)2017/5/15

講習会：KNL実践

MPI実行• ノードあたり1プロセスの最適値• HT数が異なる場合は単体OpenMPの設定を参考に• (KMP_AFFINITY, KMP_HW_SUBSET)

export OMP_NUM_THREADS=64 # 1HTの場合
export I_MPI_DEBUG=5 # コア割り当て確認
export I_MPI_PIN_DOMAIN=256
export I_MPI_PIN_PROCESSOR_EXCLUDE_LIST=0,1,68,69,
136,137,204,205 # ジッタ対策、コア除け
export KMP_AFFINITY=scatter
export KMP_HW_SUBSET=1t

177

2017/5/15

講習会：KNL実践

178

MPI実行（ノードあたり複数プロセス: 2）• PPN (Process Per Node)= 2 の場合• I_MPI_PERHOST=2

または• mpiexec.hydraの引数に“-ppn 2”を追加• I_MPI_PIN_DOMAINでプロセス毎へのコア割り
当てを指定

export OMP_NUM_THREADS=32# 1HTの場合
export I_MPI_DEBUG=5# コア割り当て確認
export I_MPI_PIN_DOMAIN=128
export I_MPI_PERHOST=2
export
I_MPI_PIN_PROCESSOR_EXCLUDE_
LIST=0,1,68,69,136,137,204,2
05 # ジッタ対策、コア除け
export KMP_AFFINITY=scatter
export KMP_HW_SUBSET=1t

2017/5/15

講習会：KNL実践

179

MPI実行（ノードあたり複数プロセス: 4）• PPN (Process Per Node)= 4 の場合• I_MPI_PERHOST=4

または• mpiexec.hydraの引数に“-ppn 4”を追加• I_MPI_PIN_DOMAINでプロセス毎へのコア割り
当てを指定

export OMP_NUM_THREADS=16# 1HTの場合
export I_MPI_DEBUG=5# コア割り当て確認
export I_MPI_PIN_DOMAIN=64
export I_MPI_PERHOST=4
export
I_MPI_PIN_PROCESSOR_EXCLUDE_
LIST=0,1,68,69,136,137,204,2
05 # ジッタ対策、コア除け
export KMP_AFFINITY=scatter
export KMP_HW_SUBSET=1t

2017/5/15

講習会：KNL実践

180

MPI実行（ノードあたり複数プロセス: 8以上、その他）• 8以上も同様に設定• I_MPI_PERHOSTの値と、I_MPI_PIN_DOMAINの値の積が256になっている必要あり、そうしないと、1コアにプロセスが偏ってしまう• I_MPI_DEBUG=5にすると、プロセスに割り当てられたコア

番号が得られるので意図通りか確認すること[40] MPI startup(): shm and tmi data transfer modes…
[0] MPI startup(): 192
269565
c3850.ofp {2,70,138,206}

2017/5/15

講習会：KNL実践

181

時間計測方法（C言語、MPI+OpenMP）
double t0, t1, t2, t_w;..すでにparallelリージョンにいると仮定#pragma omp master{
ierr = MPI_Barrier(MPI_COMM_WORLD);}#pragma omp barrier
t1 = omp_get_wtime();＜ここに測定したいプログラムを書く＞#pragma omp reduction(max: t0){t2 = omp_get_wtime();t0 = t2 - t1;}
#pragma omp master{ierr = MPI_Reduce(&t0, &t_w, 1,
MPI_DOUBLE,MPI_MAX, 0,
MPI_COMM_WORLD);バリア同期後時間を習得し保存

各プロセッサーで、ｔ0の値は異なる。
この場合は、最も遅いものの値をプロセッサ０番が受け取る

2017/5/15

182

講習会：KNL実践

時間計測方法（Fortran言語、
MPI+OpenMP）
double precision t0, t1, t2, t_w..すでにparallelリージョンにいると仮定$!omp mastercall MPI_BARRIER(MPI_COMM_WORLD, ierr)$!omp end master$!omp barrier
t1 = omp_get_wtime()＜ここに測定したいプログラムを書く＞$!omp reduction (max:t0)
t2 = omp_get_wtime()
t0 = t2 - t1$!omp end reduction$!omp mastercall MPI_REDUCE(t0, t_w, 1,&
MPI_DOUBLE_PRECISION,&MPI_MAX, 0, MPI_COMM_WORLD, ierr)$!omp end masterバリア同期後時間を習得し保存

各プロセッサで、ｔ0の値は異なる。
この場合は、最も遅いものの値をプロセッサ０番が受け取る2017/5/15

講習会：KNL実践

183

通信と計算のオーバラップ コア同士の動作モー
ドのばらつきも大き• “dynamic/runtime”• “!$omp master～!$omp end master”

いので、動的スケ
ジューリングが効くと考えられる!$omp parallel private (neib,j,k,i,X1,X2,X3,WVAL1,WVAL2,WVAL3)!$omp&
private (istart,inum,ii,ierr)!$omp masterCommunication is done by the master thread (#0)!C
!C– Send & Recv.
(…)
call MPI_WAITALL (2*NEIBPETOT, req1, sta1, ierr)!$omp end master!C!C-- Pure Inner Nodes

The master thread can join computing of internal
nodes after the completion of communication!$omp do schedule (runtime)
export OMP_SCHEDULE="dynamic,[chunksize]"
do j= 1, Ninn
(…)
enddo
!C
!C-- Boundary Nodes
Computing for boundary nodes are by all threads!$omp dodo j= Ninn+1, N
(…)
enddo

default: !$omp do schedule (static)!$omp end parallel

Idomura, Y. et al., Communication-overlap techniques for improved strong scaling of gyrokinetic Eulerian codebeyond 100k cores on the K-computer, Int. J. HPC Appl. 28, 73-86, 2014

2017/5/15

184

講習会：KNL実践

Speedup by communication overlapping(OFP: 32 nodes)• Memory model: C: Cache, F: Flat
• Sub NUMA: Q: Quadrant, N4: SNC-4

C+Q

F+Q

C+N4

F+N4

• (m) : core binding to avoid “busy”
core
C+Q(m)

F+Q(m)

C+N4(m)F+N4(m)

200

300

400

500

16%
14%
12%
10%
8%
6%
4%
2%
0%
-2%
-4%

Overlap

50

100

2017/5/15

講習会：KNL実践

演習：
サンプルプログラム集

185

2017/5/15

講習会：KNL実践

186• Ｃ言語版・Fortran90版共通ファイル：

Samples-knl.tar.gz• tarで展開後、各サンプルとともにＣ言語とFortran90言語のディレクトリが作られる• C/ : C言語用
• F/ : Fortran90言語用• 上記のファイルが置いてある場所/work/gt00/z30105 (/homeでないので注意）2017/3/6,7

講習会：MPI基礎

187

プログラムをコンパイルしよう(1/2)
1.
1.

2.
3.
4.
5.

cd コマンドを実行して Lustreファイルシステムに移動する$ cd /work/gt00/t007xx/work/gt00/z30105 にある Samples-knl.tar.gz を
自分のディレクトリにコピーする$ cp /work/gt00/z30105/Samples-knl.tar.gz ./Samples-knl.tar.gz を展開する$ tar xvfz Samples-knl.tar.gz
Samples フォルダに入る$ cd Samples-knl
アプリ名のフォルダに入る$ cd stream
C言語： $ cd C
Fortran90言語： $ cd F2017/3/6,7

講習会：MPI基礎

188

プログラムをコンパイルしよう(2/2)
6. make する$ make7. 実行ファイル(stream)ができていること

を確認する
$ ls

2017/3/6,7

講習会：MPI基礎

189

プログラムを実行しよう
1.
2.
3.

4.
5.

streamフォルダ中で以下を実行する$ pjsub stream.bash
自分の導入されたジョブを確認する$ pjstat
実行が終了すると、以下のファイルが生成される
stream.bash.eXXXXXX
stream.bash.oXXXXXX （XXXXXXは数字）
上記の標準出力ファイルの中身を見てみる$ cat stream.bash.oXXXXXX
エラー出力は以下のファイルにあるので念のため確認$ cat stream.bash.eXXXXXX