5.8K Views
May 08, 23
スライド概要
第4回5月11日 Hybrid 並列化技法(MPI と OpenMP の応用)
プログラム高速化の基礎知識、並列化プログラミング(MPI、OpenMP)の基礎知識、およびプログラム高速化の応用事例の座学を通して、計算科学で必要な高性能計算技術の基礎の習得を目指す。
https://www.r-ccs.riken.jp/outreach/schools/20230413-1/
R-CCS 計算科学研究推進室
内容に関する質問は [email protected] まで 第4回 Hybrid並列化技法 (MPIとOpenMPの応用) 名古屋大学情報基盤センター 片桐孝洋 1 2023年度 計算科学技術特論A
講義日程と内容について 2023年度 計算科学技術特論A(木曜:13:00-14:30 ) 2 第1回:プログラム高速化の基 礎、2023年4月13日 イントロダクション、ループアンローリング、キャッシュブロック化、 数値計算ライブラリの利用、その他 第2回:MPIの基礎、2023年4月20日 並列処理の基礎、MPIインターフェース、MPI通信の種類、その他 第3回:OpenMPの基礎、2023年4月27日 OpenMPの基礎、利用方法、その他 第4回:Hybrid並列化技法(MPIとOpenMPの応用)、2023年5月11日 背景、Hybrid並列化の適用事例、利用上の注意、その他 第5回:プログラム高速化実例と大規模学習への展開、2023年5月18日 プログラムの性能ボトルネック に関する考えかた(I/O、単体性能 (演算機ネック、メモリネック)、並列性能(バランス))、性能プロファイル、 機械学習におけるHPC、ほか 2023年度 計算科学技術特論A
実際の並列計算機構成例 3 2023年度 計算科学技術特論A
スーパーコンピュータ「不老」 TypeⅠサブシステム (名古屋大学情報基盤センター) 2020年7月1日正式運用~ FUJITSU Supercomputer PRIMEHPC FX1000 機種名 計算ノード CPU メインメモリ 理論演算性能 メモリバンド幅 A64FX (Armv8.2-A + SVE), 48コア+2アシスタントコア ( I/O兼計算ノードは48コア+ 4アシスタントコア ), 2.2GHz, 4ソケット相当のNUMA HBM2, 32GiB 倍精度 3.3792 TFLOPS, 単精度 6.7584 TFLOPS, 半精度 13.5168 TFLOPS 1,024 GB/s (1CMG=12コアあたり256 GB/s, 1CPU=4CMG) ノード数、総コア数 2,304ノード, 110,592コア (+4,800アシスタントコア) 総理論演算性能 7.782 PFLOPS 72 TiB 総メモリ容量 ノード間 インターコネクト ユーザ用 ローカルストレージ 冷却方式 4 世界初正式運用の スーパーコンピュータ「富岳」型 システム 自己開発のMPIプログラム向き 超並列処理用 AIツールも提供 ノード内構成 TofuインターコネクトD 各ノードは周囲の隣接ノードへ同時に合計 40.8 GB/s × 双方向 で通信可能(1リンク当たり 6.8 GB/s × 双方向, 6リンク同時通信可能) なし 水冷 2023年度 計算科学技術特論A
FX1000計算ノードの構成 HMC2 MPIプロセス 8GB 4ソケット相当、NUMA (Non Uniform Memory Access) Tofu D Network Memory Memory L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) L1 L1 L1 L1 速い L1Core L1Core L1Core Core #0 #1 #2 #3 Core Core Core #0 #1 #2 : L1データ L1 L1 キャッシュ … L1… Core : L1データ Assist. L1 64KBキャッシュ … Core Assist. …#9 … Core 遅い #3 64KB … Core ソケット0 (CMG(Core Memory Group)) ソケット2 (CMG) Assist. Core Core Core Core : L1データ Core Assist. #12 Core #13 Core #14 Core #15 Core … : L1データL1 Core L1 #12 L1 #13 L1 #14 L1 #15キャッシュ … L1 L1 ソケット1 (CMG) ソケット3 (CMG) HMC2 8GB L1 … キャッシュ L164KB … 64KB … L1 L1 5 L1 Core Core Core Core #20 Core #21 Core #22 Core #23 Core #20L1 #21 L1 #22 L1 #23 L1 … L1 ノード内合計メモリ量:32GB 読込み:240GB/秒 書込み:240GB/秒=合計:480GB/秒 L1 L1Core L1Core L1Core L1 #9 #10 #11 Core Core Core Core #9 #9 #10 #11 L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) Memory Memory ICC L1 L1 L1
FX1000通信網:TofuインターコネクトD 計算ノード内 1TOFU単位 ノード ノード ノード ノード ノード ノード ノード ノード 1TOFU単位 間の結合用 ノード ノード ノード 6 ノード ノード ・6本それぞれ 6.8GB/秒× 双方向 =13.6GB/秒 ・6リンク同時 転送可能 各ノードは周囲の隣接ノードへ 同時に合計 40.8 GB/s×双方向 で通信が可能 2023年度 計算科学技術特論A
FX1000通信網:TofuインターコネクトD 3次元接続 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 7 1 TOFU 単位 11 TOFU TOFU 単位 単位 11 TOFU TOFU 単位 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 11 TOFU TOFU 単位 単位 11 TOFU TOFU 単位 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 1 TOFU 単位 2023年度 ユーザから見ると、 X軸、Y軸、Z軸について、 奥の1TOFUと、手前の 1TOFUは、繋がってみえます (3次元トーラス接続) ただし物理結線では X軸はトーラス Y軸はメッシュ Z軸はメッシュまたは、 トーラス になっています 計算科学技術特論A
スーパーコンピュータ「不老」 クラウドシステム (名古屋大学情報基盤センター) 機種名 HPE ProLiant DL560 1ノード80コアの マルチコアCPU 計算ノード CPU Intel Xeon Gold 6230, 20コア, 2.10 - 3.90 GHz × 4 ソケット メモリ メインメモリ(DDR4 2933 MHz) 384 GiB (16 GiB × 6 枚 × 4 ソケッ ト) 理論演算性能 倍精度 5.376 TFLOPS (1.344 TFLOPS × 4 ソケット) メモリバンド幅 メインメモリ 563.136 GB/s (23.464 GB/s × 6枚 × 4 ソケット) 100 537.6 TFLOPS 総理論演算性能 (5.376 TFLOPS × 100 ノード) 37.5 TiB 総メインメモリ容量 ノード間インターコネクト InfiniBand EDR 100 Gbps ユーザ用ローカルスト なし レージ 冷却方式 空冷 ノード数 8 2023年度 研究室クラスタから移行しやすい Intel CPU搭載システム 高いノードあたりCPU性能(4ソケット) 時刻を指定してのバッチジョブ・インタラクティブ 利用が可能 ノード内 構成 計算科学技術特論A
バッチ処理とMPIジョブの投入 9 2023年度 計算科学技術特論A
「不老」のジョブ実行形態の例 以下の2通りがあります インタラクティブジョブ実行 PCでの実行のように、コマンドを入力して実行する方法 スパコン環境では、あまり一般的でない デバック用、大規模実行はできない 「不老」TypeIサブシステムでは以下に限定 最大4ノード(192コア)(標準1時間まで、最大で24時間) バッチジョブ実行 バッチジョブシステムに処理を依頼して実行する方法 スパコン環境で一般的 大規模実行用 「不老」TypeIサブシステムでは: 10 通常サービス: 最大768ノード(36,864コア)(24時間まで) 申込み制: 2304ノード(110,592コア)(実行時間制限無し) 2023年度 計算科学技術特論A
バッチ処理とは スパコン環境では、インタラクティブ実行(コマンドラインで実 行すること)は提供されていないことがあります。特に、大規 模並列実行ができないようになっています。 ジョブはバッチ処理で実行します。 バッチキュー バッチ処理 システムが ジョブを取り出す ジョブの依頼 実行 ユーザ 11 スパコン 2023年度 計算科学技術特論A
コンパイラの種類とインタラクティブ実行 およびバッチ実行の例 インタラクティブ実行、およびバッチ実行で、利用するコンパイラ (C言語、C++言語、Fortran90言語)の種類が違います インタラクティブ実行では オウンコンパイラ(そのノードで実行する実行ファイルを生成する コンパイラ)を使います バッチ実行では クロスコンパイラ(そのノードでは実行できないが、バッチ実行する時の ノードで実行できる実行ファイルを生成するコンパイラ)を使います それぞれの形式(富士通社の例) オウンコンパイラ: <コンパイラの種類名> クロスコンパイラ: <コンパイラの種類名>px 例)富士通Fortran90コンパイラ 12 オウンコンパイラ: frt クロスコンパイラ: frtpx 2023年度 計算科学技術特論A
バッチキューの設定のしかた 13 バッチ処理は、富士通社のバッチシステム(PJM) で管理されています。 以下、主要コマンドを説明します。 ジョブの投入: pjsub <ジョブスクリプトファイル名> 自分が投入したジョブの状況確認: pjstat もしくは pjstat2 投入ジョブの削除: pjdel <ジョブID> バッチキューの状態を見る: pjstat2 --rsc -b もしくは pjstat2 --use システム制限値を見る: pjstat2 --rsc –x 2023年度 計算科学技術特論A
インタラクティブ実行のやり方の例 コマンドラインで以下を入力 1ノード実行用 $ pjsub -L "rscgrp=fx-interactive" --interact 4ノード実行用 $ pjsub -L “rscgrp=fx-interactive,node=4” --interact 14 2023年度 計算科学技術特論A
pjstat2 --rsc の実行画面例 $ pjstat2 --rsc RSCGRP fx-interactive fx-small fx-debug fx-extra fx-middle fx-large fx-xlarge fx-special fx-middle2 15 STATUS [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] [ENABLE,START] 使える キュー名 (リソース グループ) 現在使えるか NODE 384: 4x6x16 384: 4x6x16 384: 4x6x16 384: 4x6x16 1536: 8x12x16 1536: 8x12x16 1536: 8x12x16 2304: 12x12x16 1536: 8x12x16 ノードの ENABLE: キューに 物理構成情報 ジョブ投入可能 START: ジョブが 2023年度 計算科学技術特論A 流れている
pjstat2 --rsc -x の実行画面例 $ pjstat2 --rsc -x RSCGRP fx-interactive fx-small fx-debug fx-extra fx-middle fx-large fx-xlarge fx-special fx-middle2 STATUS MIN_NODE [ENABLE,START] 1 [ENABLE,START] 1 [ENABLE,START] 1 [ENABLE,START] 1 [ENABLE,START] 12 [ENABLE,START] 96 [ENABLE,START] 96 [ENABLE,START] 1 [ENABLE,START] 1 最小 ノード 数 16 最大 ノード 数 MAX_NODE 4 24 36 36 96 192 768 2304 96 最大 実行時間 2023年度 計算科学技術特論A MAX_ELAPSE MEM(GB) 24:00:00 28 168:00:00 28 01:00:00 28 12:00:00 28 72:00:00 28 72:00:00 28 24:00:00 28 unlimited 28 72:00:00 28
pjstat2 --rsc -b の実行画面例 $ pjstat2 --rsc -b RSCGRP fx-interactive fx-small fx-debug fx-extra fx-middle fx-large fx-xlarge fx-special fx-middle2 STATUS TOTAL RUNNING QUEUED HOLD OTHER NODE [ENABLE,START] 1 1 0 0 0 384:4x6x16 [ENABLE,START] 83 33 50 0 2 384:4x6x16 [ENABLE,START] 40 22 18 0 0 384:4x6x16 [ENABLE,START] 20 8 12 0 2 384:4x6x16 [ENABLE,START] 33 7 26 0 0 1536:8x12x16 [ENABLE,START] 10 3 7 0 0 1536:8x12x16 [ENABLE,START] 5 1 4 0 0 1536:8x12x16 [ENABLE,START] 2 0 2 0 0 304:12x12x16 [ENABLE,START] 10 2 8 0 0 1536:8x12x16 総合 ジョブ数 17 実行中 ジョブ数 待たされている ジョブ数 2023年度 計算科学技術特論A
pjstat2 --use の実行画面例 $ pjstat2 --use RSCGRP Used nodes/ Total nodes fx-debug groups (total 384 nodes) 360/ 384 fx-interactive ------------------------- 0% 0 fx-small ************************- 94% 360 fx-debug ------------------------0% 0 fx groups (total 1536 nodes) 860/ 1536 fx-middle *****-------------------- 18% 284 fx-middle2 ------------------------0% 0 fx-large ******------------------21% 320 fx-xlarge *****-------------------- 17% 256 fx-extra *******-----------------27% 104/ 384 fx-special ------------------------0% 0/ 2304 fx-workshop ------------------------- 0% 0/ 384 当該キューに 割り当てられた ノード数の何%が 使われているか 18 使われている ノード数 2023年度 当該キューに割り当て られているノード数 (キュー間で重複あり) 計算科学技術特論A
pjstat2 の実行画面例 $ pjstat2 JOB_ID 95647 JOB_NAME STATUS hello-pure RUNNING ジョブID 19 GROUP RSCGROUP jhpcn2602 fx-debug START_DATE (09/15 16:47)< 実行してい るか: RUNNING: 実行中 2023年度 計算科学技術特論A ELAPSE 00:00:00 NODE 12
JOBスクリプトサンプルの説明(ピュアMPI) (hello-pure.bash, C言語、Fortran言語共通) #!/bin/bash #PJM -L "rscunit=fx" #PJM -L "rscgrp=fx-workshop" #PJM -L "node=12" #PJM --mpi "proc=576" #PJM -L "elapse=1:00" mpirun ./hello MPIジョブを48*12ノード = 576プロセス で実行する 20 2023年度 計算科学技術特論A リソースグループ名 :fx-workshop 利用ノード数 利用コア数 (MPIプロセス数) 実行時間制限 :1分
FX1000計算ノードの構成 HMC2 MPIプロセス 8GB 4ソケット相当、NUMA (Non Uniform Memory Access) Tofu D Network Memory Memory L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) L1 Core #0 L1 L1 L1 L1Core L1Core L1Core #1 #2 #3 Core Core Core #0 #1 #2 : L1データ L1 L1 キャッシュ … L1… Core : L1データ Assist. L1 64KBキャッシュ … Core Assist. … …#9 Core #3 64KB … Core ソケット0 (CMG(Core Memory Group)) ソケット2 (CMG) Assist. Core Core Core Core : L1データ Core Assist. #12 Core #13 Core #14 Core #15 Core … : L1データL1 Core L1 #12 L1 #13 L1 #14 L1 #15キャッシュ … L1 L1 ソケット1 (CMG) ソケット3 (CMG) HMC2 8GB L1 … キャッシュ L164KB … 64KB … L1 L1 L1 L1 L1Core L1Core L1Core L1 #9 #10 #11 Core Core Core Core #9 #9 #10 #11 Core Core Core Core #20 Core #21 Core #22 Core #23 Core #20L1 #21 L1 #22 L1 #23 L1 … L1 L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) Memory Memory ノード内合計メモリ量:32GB 21 ICC 読込み:240GB/秒 「不老」利用型MPI講習会 2023年度 計算科学技術特論A 書込み:240GB/秒=合計:480GB/秒 L1 L1 L1
並列版Helloプログラムを実行しよう (ピュアMPI) 1. 2. 3. 4. 5. 22 Helloフォルダ中で以下を実行する $ pjsub hello-pure.bash 自分の導入されたジョブを確認する $ pjstat 実行が終了すると、以下のファイルが生成される hello-pure.bash.eXXXXXX hello-pure.bash.oXXXXXX (XXXXXXは数字) 上記の標準出力ファイルの中身を見てみる $ cat hello-pure.bash.oXXXXXX “Hello parallel world!”が、 48プロセス*12ノード=576個表示されていたら成功。 2023年度 計算科学技術特論A
バッチジョブ実行による標準出力、 標準エラー出力 バッチジョブの実行が終了すると、標準出力ファイルと 標準エラー出力ファイルが、ジョブ投入時のディレクトリ に作成されます。 標準出力ファイルにはジョブ実行中の標準出力、 標準エラー出力ファイルにはジョブ実行中の エラーメッセージが出力されます。 ジョブ名.oXXXXX --- 標準出力ファイル ジョブ名.eXXXXX --- 標準エラー出力ファイル (XXXXX はジョブ投入時に表示されるジョブのジョブID) 23 2023年度 計算科学技術特論A
並列版Helloプログラムを実行しよう (ハイブリッドMPI) (準備) Helloフォルダ中で以下を実行する $ make clean $ cp Makefile_hy48 Makefile $ make 24 2023年度 計算科学技術特論A
並列版Helloプログラムを実行しよう (ハイブリッドMPI) 1. 2. 3. 4. 5. Helloフォルダ中で以下を実行する $ pjsub hello-hy48.bash 自分の導入されたジョブを確認する $ pjstat 実行が終了すると、以下のファイルが生成される hello-hy48.bash.eXXXXXX hello-hy48.bash.oXXXXXX (XXXXXXは数字) 上記標準出力ファイルの中身を見てみる $ cat hello-hy48.bash.oXXXXXX “Hello parallel world!”が、 1プロセス*12ノード=12 個表示されていたら成功。 25 2023年度 計算科学技術特論A
JOBスクリプトサンプルの説明(ハイブリッドMPI) (hello-hy48.bash, C言語、Fortran言語共通) #!/bin/bash #PJM -L "rscunit=fx" #PJM -L "rscgrp=fx-workshop" #PJM -L "node=12" #PJM --mpi "proc=12" #PJM -L "elapse=1:00" export OMP_NUM_THREADS=48 mpirun ./hello MPIジョブを1*12 = 12 プロセスで 実行する。 26 2023年度 リソースグループ名 :fx-workshop 利用ノード数 利用コア数 (MPIプロセス数) 実行時間制限:1分 1MPIプロセス当たり 48スレッド生成 ※ただし効率的な 実行形式ではありません 計算科学技術特論A
FX1000計算ノードの構成 HMC2 MPIプロセス 8GB スレッド 4ソケット相当、NUMA (Non Uniform Memory Access) Tofu D Network Memory Memory L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) L1 L1 Core #0 L1 L1 L1Core L1Core L1Core #1 #2 #3 Core Core Core #0 #1 #2 : L1データ L1 L1 キャッシュ … L1… Core : L1データ Assist. L1 64KBキャッシュ … Core Assist. … …#9 Core #3 64KB … Core ソケット0 (CMG(Core Memory Group)) ソケット2 (CMG) Assist. Core Core Core Core : L1データ Core Assist. #12 Core #13 Core #14 Core #15 Core … : L1データL1 Core L1 #12 L1 #13 L1 #14 L1 #15キャッシュ … L1 L1 ソケット1 (CMG) ソケット3 (CMG) HMC2 8GB L1 … キャッシュ L164KB … 64KB … L1 L1 L1 Core Core Core Core #20 Core #21 Core #22 Core #23 Core #20L1 #21 L1 #22 L1 #23 L1 … L1 Memory Memory ノード内合計メモリ量:32GB 27 L1 L1Core L1Core L1Core L1 #9 #10 #11 Core Core Core Core #9 #9 #10 #11 L2 (12コアで共有、12MB) L2 (12コアで共有、12MB) 読込み:512GB/秒 2023年度 書込み:512GB/秒=合計:1024GB/秒 ICC 計算科学技術特論A L1 L1 L1
MPI実行時のリダイレクトについて 一般に、スーパーコンピュータでは、 MPI実行時の入出力のリダイレクトができません ×例)mpirun ./a.out < in.txt > out.txt 専用のリダイレクト命令が用意されています。 FX10でリダイレクトを行う場合、以下のオプションを 指定します。 ○例) mpirun --stdin ./in.txt --stdout out.txt ./a.out 28 2023年度 計算科学技術特論A
MPIプロセスのノード割り当て
「不老」TypeIサブシステムでは、何もしないと(デフォルトでは)、
確保ノードが物理的に連続に確保されない
⇒通信性能が劣化する場合がある
物理的に連続したノード割り当てをしたい場合は、
ジョブスクリプトにその形状を記載する
ただしノード割り当て形状を指定すると、待ち時間が増加する
記載法: #PJM -L “node= <形状>:<機能>“
<形状>:= { 1次元 | 2次元 | 3次元 }
<機能> := { 離散 | メッシュ | トーラス }
離散 : = { noncont }, メッシュ := {mesh}, トーラス := {torus}:12ノード以上
例:24ノード、3次元(2x4x3)、トーラス
29
1次元 := { a }, 2次元 := {a x b}, 3次元 := {a x b x c}
#PJM -L “node= 2x4x3 : torus“
2023年度
計算科学技術特論A
NUMA affinity指定について NUMA計算機では、MPIプロセスのソケットへ の割り当てが性能面で重要となる (NUMA affinityとよぶ) MPIプロセスのソケット(富士通用語でCMC) の割り当ては、「不老」TypeIサブシステムでは 富士通社のNUMA affinity (MCAパラメタ)で 設定する 環境変数で設定する 30 2023年度 計算科学技術特論A
NUMAメモリポリシー指定 環境変数名:plm_ple_memory_allocation_policy 代入する値 localalloc: プロセスが動作中のCPU(コア)の属するNUMAノードからメモリを割り当てる。 interleave_local: プロセスの「ローカルノード集合」内の各NUMAノードから交互にメモリ割り当てる。 interleave_nonlocal: プロセスの「非ローカルノード集合」内の各NUMAノードから交互にメモリ割り当てる。 interleave_all: プロセスの「全ノード集合」内の各NUMAノードから交互にメモリを取得する。 bind_local: プロセスの「ローカルノード集合」に属する各NUMAノードで、ノードIDの若い順にメモリ割り当てを 行う。 bind_nonlocal: プロセスの「非ローカルノード集合」に属する各NUMAノードで、ノードIDの若い順にメモリ割り 当てを行う。 bind_all: プロセスの「全ノード集合」のNUMAノードにバインドする。 prefer_local: プロセスの「ローカルノード集合」のうち、NUMAノードIDが最も若いものを「優先ノード」とし、「優 先ノード」からメモリ割り当てを行う。 prefer_nonlocal: プロセスの「非ローカルノード集合」のうち、NUMAノードIDが最も若いも のを「優先ノード」とし、「優先ノード」からメモリ割り当てを行う。 通常は、localallocでよい。 export plm_ple_memory_allocation_policy=localalloc 31 2023年度 計算科学技術特論A
CPU(コア)割り当てポリシー指定 環境変数名:plm_ple_numanode_assign_policy 代入する値 simplex: NUMAノードを占有するように割り当てる。 share_cyclic: NUMAノードを他のプロセスと共有するように割り当てる。異なるNUMAノードに 順番にプロセスを割り当てる。 share_band: NUMAノードを他のプロセスと共有するように割り当てる。同一NUMAノードに 連続してプロセスを割り当てる。 例) export plm_ple_numanode_assign_policy=simplex 各ソケットを各MPIプロセスで独占したいときはsimplexを指定 各ノードへ割り当てるMPIプロセス数が2個で、それぞれのMPIプロセスは 16個のスレッド実行するとき MPIプロセスをプロセス順に各ソケットに詰め込みたいときは、 share_bandを指定 ノード当たり32個のMPIプロセスを、ランク番号が 近い順に割り当てたい場合 32 2023年度 計算科学技術特論A
その他の注意事項(その1) MPI用のコンパイラを使うこと MPI用のコンパイラを使わないと、MPI関数 が未定義というエラーが出て、コンパイル できなくなる 例えば、以下のコマンド Fortran90言語: mpif90 C言語: mpicc C++言語: mpixx, mpic++ コンパイラオプションは、逐次コンパイラと同じ 33 2023年度 計算科学技術特論A
その他の注意事項(その2) ハイブリッドMPIの実行形態 (MPIプロセス数)×(MPIプロセス当たりのOpenMPスレッド数) <= 利用コア総数 34 HT(Intel)やSMT(IBM)などの、物理コア数の定数倍の スレッドが実行できるハードの場合 (例えば、KNL) スレッド数(論理スレッド数、例えばHTの数で、物理コアの 4倍まで等)が、上記の利用コア総数に相当で換算 以上を超えても実行できるが、性能が落ちる 必ずしも、1ノード内に1MPIプロセス実行が高速とはならない 一般に、OpenMPによる台数効果が8~16スレッド(経験値、 問題やハードウェア依存) を超えると悪くなるため。 効率の良いハイブリッドMPI実行には、 効率の良いOpenMP実装が必須 2023年度 計算科学技術特論A
並列処理の評価指標: 弱スケーリングと強スケーリング 35 2023年度 計算科学技術特論A
弱スケーリング (Weak Scaling) ノードあたりの問題サイズを固定し、並列処理時の全体の問題サイズを増加す ることで、性能評価をする方法 問題サイズN ときの計算量がO(N)である場合、並列処理のノード数が増加し ても、理想的な実行時間は変わらないと期待できる 一般的にノード数が増加すると(主にシステム的な要因により) 通信時間が増大するため、そうはならない 該当する処理は 陽解法のシミュレーション全般 陰解法で、かつ連立一次方程式の解法に反復解法を用いているシミュレーション 1ノードあたりの 問題サイズ 8ノード実行での問題サイズ 36 2023年度 64ノード実行での問題サイズ 計算科学技術特論A
強スケーリング (Strong Scaling) 全体の問題サイズを固定し、ノード数を増加することで 性能評価をする方法 理想的な実行時間は、ノード数に反比例して減少する。 一般的にノード数が増加すると1ノードあたりの問題サイズが減少し、 通信時間の占める割合が増大するため、理想的に実行時間は減少しない 該当する処理は 計算量が膨大なアプリケーション 例えば、連立一次方程式の解法。データ量O (N 2 )に対して、計算量はO ( N 3 ) 固定した 問題サイズ 37 8ノード実行での問題サイズ 2023年度 64ノード実行での問題サイズ 計算科学技術特論A
弱スケーリングと強スケーリング 適用アプリの特徴 弱スケーリングが適用できるアプリケーションは、 原理的に通信が少ないアプリケーション 強スケーリングを適用しないといけないアプリケーションは、 計算量が膨大になるアプリケーション 38 領域分割法などにより、並列化できるアプリケーション 主な通信は、隣接するプロセス間のみ ノード数を増すことで、実行時間の面で容易に問題サイズを大規模化 通信時間の占める割合が超並列実行でも少ないアプリケーション 全体の問題サイズは、実行時間の制約から大規模化できない そのため、1ノードあたりの問題サイズは、ノード数が多い状況で 小さくなる その結果、通信処理の占める時間がほとんどになる 超並列実行時で通信処理の最適化が重要になるアプリケーション 2023年度 計算科学技術特論A
強スケールアプリケーションの問題 TOP500で採用されているLINPACK 密行列に対する連立一次方程式の解法のアプリケーション 2022年11月のTOP500の、コア当たりの問題サイズ (1位)Frontier、 GPUマシン N= 24,440,832 (2444万次元)、#cores= 8,730,112 (873万コア)、N/#cores=2.79 (2位)スーパーコンピュータ「富岳」、 CPUマシン N= 21,288,960 (2128万次元)、#cores=7,630,848 (763万コア)、N/#cores=2.78 (5位)Summit、GPUマシン N= 16,473,600 (1647万次元)、#cores=2,414,592 (241万コア)、N/#cores=6.83 上位のマシン、および、CPUマシンほど、コア当たりの問題サイズ が小さい傾向がある ←通信時間の占める割合が大きくなりやすい 今後コア数が増加すると、通信時間の削減が問題になる 39 2023年度 計算科学技術特論A
ピュアMPIプログラム開発 の基礎 40 2023年度 計算科学技術特論A
MPI並列化の大前提(再確認) SPMD 対象のメインプログラムは、 すべてのコア上で、かつ、 同時に起動された状態 から処理が始まる。 分散メモリ型並列計算機 41 各プロセスは、完全に独立したメモリを 持っている。(共有メモリではない) 2023年度 計算科学技術特論A
並列化の考え方(C言語) SIMDアルゴリズムの考え方(4プロセスの場合) 行列A for ( j=0; j<n/4; j++) { 内積( j, i ) } 各PEで 重複して 所有する プロセス0 for ( j=0; j<n; j++) { 内積( j, i ) } for ( j=n/4; j<(n/4)*2; j++) { 内積( j, i ) } プロセス1 for ( j=(n/4)*2; j<(n/4)*3; j++) { 内積( j, i ) } プロセス2 for ( j=(n/4)*3; j<n; j++) { 内積( j, i ) } プロセス3 42 2023年度 計算科学技術特論A ベクトルx
並列化の考え方(Fortran言語) SIMDアルゴリズムの考え方(4プロセスの場合) 行列A プロセス0 do j=1, n 内積( j, i ) enddo do j=1, n/4 内積( j, i ) enddo 各プロセスで 重複して所有する do j=n/4+1, (n/4)*2 内積( j, i ) プロセス1 enddo do j=(n/4)*2+1, (n/4)*3 内積( j, i ) プロセス2 enddo do j=(n/4)*3+1, n 内積( j, i ) プロセス3 enddo 43 2023年度 計算科学技術特論A ベクトルx
初心者が注意すること 各プロセスでは、独立した配列が個別に確保されます。 PE0 A[N][N] PE1 PE2 A[N][N] A[N][N] PE3 A[N][N] myid変数は、MPI_Init()関数が呼ばれた段階で、 各プロセス固有の値になっています。 PE0 myid = 0 44 PE1 PE2 myid = 2 myid = 1 2023年度 計算科学技術特論A PE3 myid = 3
並列プログラム開発の指針 正しく動作する逐次プログラムを作成する 1.のプログラムで、適切なテスト問題を作成する 2.のテスト問題の実行について、適切な処理の単位 ごとに、正常動作する計算結果を確認する 1.の逐次プログラムを並列化し、並列プログラミング を行う 2.のテスト問題を実行して動作検証する このとき3.の演算結果と比較し、正常動作をすることを 確認する。もし異常であれば、4.に戻りデバックを行う。 1. 2. 3. 4. 5. 6. いきなり並列化しない! 45 2023年度 開発工数が上がる要因 計算科学技術特論A
数値計算プログラムの特徴を利用して 並列化時のデバックをする 数値計算プログラムの処理単位は、プログラム上の 基本ブロック(ループ単位など)ではなく、数値計算上の 処理単位(数式レベルで記述できる単位)となる 離散化(行列作成)部分、行列分解部分(LU分解法部分 (LU分解部分、前進代入部分、後退代入部分))、など 演算結果は、なんらかの数値解析上の意味において検証 46 理論解(解析解)とどれだけ離れているか、考えられる丸め誤差 の範囲内にあるか、など 計算された物理量(例えば流速など)が物理的に妥当な範囲内 にあるか、など 両者が不明な場合でも、数値的に妥当であると思われる逐次の 結果と比べ、並列化した結果の誤差が十分に小さいか、など 2023年度 計算科学技術特論A
並列化の方針 I. II. III. IV. ステップ1:簡易並列化 逐次プログラムと同様の配列確保をする 並列化対象となるループ変数の開始値と終了値を 書き換える 最低限の通信を実装する 動作を確認し、プログラムを完成させる ステップ2:完全並列化 分散された必要最低限のメモリ確保をする VI. 並列化対象となるループ変数の開始値と終了値を 書き換える VII. 配列アクセスの書き方を書き換える VIII. 通信を実装する IX. 動作を確認し、プログラムを完成させる 47 2023年度 計算科学技術特論A V.
並列化の方針 (行列-ベクトル積、C言語) 全プロセスで行列AをN×Nの大きさ、ベクトルx、yを Nの大きさ、確保してよいとする。 各プロセスは、担当の範囲のみ計算するように、 ループの開始値と終了値を変更する。 1. 2. ブロック分散方式では、以下になる。 (n が numprocs で割り切れる場合) ib = n / numprocs; for ( j=myid*ib; j<(myid+1)*ib; j++) {…} (2の並列化が完全に終了したら)各プロセスで担当の データ部分しか行列を確保しないように変更する。 3. 48 上記のループは、以下のようになる。 for ( j=0; j<ib; j++) { … } 2023年度 計算科学技術特論A
並列化の方針 (行列-ベクトル積、Fortran言語) 全プロセスで行列AをN×Nの大きさ、ベクトルx、yを Nの大きさ、確保してよいとする。 各プロセスは、担当の範囲のみ計算するように、 ループの開始値と終了値を変更する。 1. 2. ブロック分散方式では、以下になる。 (n が numprocs で割り切れる場合) ib = n / numprocs do j=myid*ib+1, (myid+1)*ib … enddo (2の並列化が完全に終了したら)各プロセスで担当の データ部分しか行列を確保しないように変更する。 3. 49 上記のループは、以下のようになる。 do j=1, ib … enddo 2023年度 計算科学技術特論A
データ分散方式に関する注意 負荷分散を考慮し、多様なデータ分散方式を採用可能 数学的に単純なデータ分散方式が良い ◎:ブロック分散、サイクリック分散(ブロック幅=1) △~〇:ブロック・サイクリック分散(ブロック幅=任意) 理由: 複雑な(一般的な)データ分散は、各MPIプロセスが所有する データ分散情報(インデックスリスト)を必要とするため、 メモリ量が余分に必要なる 例:1万並列では、少なくとも1万次元の整数配列が必要 ⇒分散して配列を所有しないとメモリを圧迫し大規模化できない 数学的に単純なデータ分散の場合は インデックスリストは不要 ⇒ローカルインデックス、グローバルインデックスが計算で求まるため 50 2023年度 計算科学技術特論A
並列化の方針(行列-ベクトル積) (C言語) 全PEでN×N行列を持つ場合 PE0 for ( j=(n/4)*2; j<(n/4)*3; j++) { 内積( j, i ) } for ( j=0; j<(n/4); j++) { 内積( j, i ) } PE2 PE1 for ( j=(n/4)*3; j<n; j++) { 内積( j, i ) } for ( j=(n/4); j<(n/4)*2; j++) { 内積( j, i ) } PE3 ※各PEで使われない領域が出るが、担当範囲指定がしやすいので実装がしやすい。 51 2023年度 計算科学技術特論A
並列化の方針(行列-ベクトル積) (Fortran 言語) 全PEでN×N行列を持つ場合 do j=(n/4)*2+1, (n/4)*3 内積( j, i ) enddo PE0 do j=1, n/4 内積( j, i ) enddo PE2 do j=(n/4)*3+1, n 内積( j, i ) enddo PE1 do j=n/4+1, (n/4)*2 内積( j, i ) enddo PE3 ※各PEで使われない領域が出るが、担当範囲指定がしやすいので実装がしやすい。 52 2023年度 計算科学技術特論A
並列化の方針(行列-ベクトル積) この方針では、y=Ax のベクトルy は、以下の ように一部分しか計算されないことに注意! PE0 = = = PE1 PE2 = PE3 53 2023年度 計算科学技術特論A
並列化の方針のまとめ 行列全体(A[N][N])を各プロセスで確保することで、 SIMDの考え方を、逐次プログラムに容易に適用できる ループの開始値、終了値のみ変更すれば、並列化が完成する この考え方は、MPI、OpenMPに依存せず、適用できる。 欠点 手順3のデバックの困難性を低減できる 54 最大実行可能な問題サイズが、利用ノード数によらず、1ノードあたり のメモリ量で制限される(メモリに関するスケーラビリティが無い) 完全な並列化(手順3)の際、手順2での正しい 計算結果を参照できる 数値計算上の処理単位ごとに、個別に並列化ができる (モジュールごとに、デバックできる) 2023年度 計算科学技術特論A
行列‐ベクトル積のピュアMPI並列化の例
(C言語)
ierr = MPI_Init(&argc, &argv);
ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
ierr = MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
…
ib = n/numprocs;
ブロック分散を仮定した
jstart = myid * ib;
担当ループ範囲の定義
jend = (myid+1) * ib;
if ( myid == numprocs-1) jend=n;
for( j=jstart; j<jend; j++) {
y[ j ] = 0.0;
for(i=0; i<n; i++) {
y[ j ] += A[ j ][ i ] * x[ i ];
}
}
55
MPIプロセスの担当ごとに
縮小したループの構成
2023年度
計算科学技術特論A
行列‐ベクトル積のピュアMPI並列化の例 (Fortran言語) call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr) … ib = n/numprocs ブロック分散を仮定した jstart = 1 + myid * ib jend = (myid+1) * ib 担当ループ範囲の定義 if ( myid .eq. numprocs-1) jend = n do j = jstart, jend y( j ) = 0.0d0 do i=1, n y( j ) = y( j ) + A( j, i ) * x( i ) enddo enddo 56 MPIプロセスの担当ごとに 縮小したループの構成 2023年度 計算科学技術特論A
nがMPIプロセス数で割切れない時 nがプロセス数のnumprocsで割り切れない場合 配列確保: A(N/numprocs + mod(N, numprocs), N) ループ終了値:numprocs-1のみ終了値がnとなるように実装 ib = n / numprocs; if ( myid == (numprocs - 1) ) { i_end = n; } else { i_end = (myid+1)*ib; } for ( i=myid*ib; i<i_end; i++) { … } 57 2023年度 計算科学技術特論A
余りが多い場合 mod(N, numprocs)が大きいと、負荷バランスが悪化 58 例:N=10、numprocs=6 int(10/6)=1なので、 プロセス0~5は1個のデータ、プロセス6は4個のデータを持つ 各プロセスごとの開始値、終了値のリストを持てば改善可能 プロセス0: i_start(0)=1, i_end(0)=2, 2個 プロセス1: i_start(1)=3, i_end(1)=4, 2個 プロセス2: i_start(2)=5, i_end(2)=6, 2個 プロセス3: i_start(3)=7, i_end(3)=8, 2個 プロセス4: i_start(4)=9, i_end(4)=9, 1個 プロセス5: i_start(5)=10, i_end(5)=10, 1個 欠点:プロセス数が多いと、上記リストのメモリ量が増える 2023年度 計算科学技術特論A
ハイブリットMPIプログラム開発 の基礎 59 2023年度 計算科学技術特論A
用語の説明 ピュアMPI実行 ハイブリッドMPI実行 並列プログラムでMPIのみ利用 MPIプロセスのみ 並列プログラムでMPIと何か(X(エックス))を利用 MPIプロセスと何か(X)の混合 何か(X)は、OpenMPによるスレッド実行、もしくは、GPU実行が主流 「MPI+X」の実行形態 上記のハイブリッドMPI実行と同義として使われる Xは、OpenMPや自動並列化によるスレッド実行、CUDAなどの GPU向き実装、OpenACCなどのGPUやメニーコア向き実行、 などの組合せがある。主流となる計算機アーキテクチャで変わる。 60 2023年度 計算科学技術特論A
ハイブリッドMPI実行の目的 同一の資源量(総コア数)の利用に対し ピュアMPI実行でのMPIプロセス数に対し、ハイブリッドMPI実行 でMPIプロセス数を減らすことで、通信時間を削減する ことが主な目的 例)JCAHPC(東大・筑波大) の Oakforest-PACS 全系は8,208ノード、558,144(55万)物理コア ピュアMPI実行(HT4利用時) :2,232,576 (223万)プロセス実行 ハイブリッドMPI実行(HT4利用時): (1ノード272スレッド実行):8,208プロセス MPIプロセス数の比は272倍! 61 2023年度 計算科学技術特論A
[秒] 800 ハイブリッドMPI/OpenMP実行の実例 (ある有限差分法のアプリ) 682 700 ハイブリッドMPI/OpenMP Xeon Phi (KNC) : 8ノード (最大:1920 スレッド) 569 600 500 MPI/OpenMP実行形態に依存し 実行時間の差が増大! PXTY : Xプロセス、Tスレッド/プロセス 379 400 310 300 200 245 ピュアMPI 100 0 290 361 Total Execution Time 62 ハイブリッドMPI/OpenMP の実行形態 P8T240 P16T120 P32T60 P64T30 P128T15 P240T8 P480T4
ハイブリッドMPI/OpenMP 並列プログラム開発の指針 1. 2. 3. 4. 5. 6. 正しく動作するピュアMPIプログラムを開発する OpenMPを用いて対象カーネルをスレッド並列化する 2.の性能評価をする 3.の評価結果から性能が不十分な場合、 対象カーネルについてOpenMPを用いた 性能チューニングを行う。 性能に問題がある場合、3.へ戻る。 全体性能を検証し、通信時間に問題がある場合、 通信処理のチューニングを行う。 63 2023年度 計算科学技術特論A
ハイブリッドMPI/OpenMP並列化の方針 (OpenMPプログラムがある場合) すでに開発済みのOpenMPプログラムを元にMPI化する場合 OpenMPのparallelループをMPI化すること OpenMPループ中にMPIループを記載すると OK 通信多発で遅くなるか、最悪、動作しない !$omp parallel do do i=1, n … do j=1, n … enddo enddo !$omp end parallel do 64 NG !$omp parallel do do i=1, n … do j=istart, iend call MPI_send(…) … enddo enddo !$omp end parallel do 2023年度 計算科学技術特論A !$omp parallel do do i=istart, iend … do j=1, n … enddo … enddo !$omp end parallel do call MPI_send(…)
行列‐ベクトル積の
ハイブリッドMPI並列化の例(C言語)
ierr = MPI_Init(&argc, &argv);
ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
ierr = MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
…
ib = n/numprocs;
ブロック分散を仮定した
jstart = myid * ib;
担当ループ範囲の定義
jend = (myid+1) * ib;
if ( myid == numprocs-1) jend=n;
#pragma omp parallel for private(i)
この一文を追加するだけ!
for( j=jstart; j<jend; j++) {
y[ j ] = 0.0;
MPIプロセスの担当ごとに
for(i=0; i<n; i++) {
縮小したループの構成
y[ j ] += A[ j ][ i ] * x[ i ];
}
}
65
2023年度
計算科学技術特論A
行列‐ベクトル積の ハイブリッドMPI並列化の例(Fortran言語) call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr) … ib = n/numprocs jstart = 1 + myid * ib ブロック分散を仮定した jend = (myid+1) * ib 担当ループ範囲の定義 if ( myid .eq. numprocs-1) jend = n !$omp parallel do private(i) この文を追加するだけ! do j = jstart, jend y( j ) = 0.0d0 MPIプロセスの担当ごとに do i=1, n y( j ) = y( j ) + A( j, i ) * x( i ) 縮小したループの構成 enddo enddo !$omp end parallel do 66 2023年度 計算科学技術特論A
ハイブリッドMPI/OpenMP実行の注意点 (その1) ハイブリッドMPI/OpenMP実行では、MPIプロセス数に加えて、 スレッド数がチューニングパラメタとなり、複雑化する。 例)1ノード、16コア実行 4MPIプロセス、4スレッド実行 2MPIプロセス、8スレッド実行 コ コ コ コ コ コ コ コ コ コ コ コ ア ア ア ア ア ア ア ア ア ア ア ア 1 1 0 1 2 3 4 5 6 7 8 9 0 1 コ ア 1 2 コ ア 1 3 コ ア 1 4 コ ア 1 5 コ コ コ コ コ コ コ コ コ コ コ コ ア ア ア ア ア ア ア ア ア ア ア ア 1 1 0 1 2 3 4 5 6 7 8 9 0 1 コ ア 1 2 コ ア 1 3 コ ア 1 4 コ ア 1 5 1つのMPI プロセス の割り当て 対象 ccNUMAの計算機では、ソケット数ごとに1MPIプロセス実行 が高速となる可能性がある(ハードウェア的に) 例)スーパーコンピュータ「富岳」(4ソケット相当、48コア) 4MPIプロセス、12スレッド実行 コ コ コ コ コ コ コ コ コ コ コ コ ア ア ア ア ア ア ア ア ア ア ア ア 1 1 0 1 2 3 4 5 6 7 8 9 0 1 CMG0(ソケット0) 67 コ コ コ コ コ コ コ コ コ コ コ コ ア ア ア ア ア ア ア ア ア ア ア ア 1 1 0 1 2 3 4 5 6 7 8 9 0 1 CMG1(ソケット1) 2023年度 コ コ コ コ コ コ コ コ コ コ コ コ ア ア ア ア ア ア ア ア ア ア ア ア 1 1 コ コ 0 1 2 3 コ 4コ 5コ 6コ 7 コ 8 コ 9 コ コ コ コ 0 1 ア ア ア ア ア ア ア ア ア ア ア ア 1 1 0 1 2 3 4 5 6 7 8 9 0 1 CMG2 (ソケット2) 計算科学技術特論A CMG3 (ソケット3)
ハイブリッドMPI/OpenMP実行の注意点 (その2) ハイブリッドMPI/OpenMP実行の実行効率を決める要因 ハイブリッドMPI化による通信時間の削減割合 OpenMP等で実現される演算処理のスレッド実行効率 1. 2. 特に、2は注意が必要。 単純な実装だと、【経験的に】8~16スレッド並列を超えると、 スレッド実行時の台数効果が劇的に悪くなる。 効率の良いスレッド並列化の実装をすると、 ハイブリッドMPI/OpenMP実行時に効果がより顕著になる。 1. 2. 3. 68 実装の工夫が必要。たとえば ファーストタッチ(すでに説明済み)の適用 メモリ量や演算量を増加させても、スレッドレベルの並列性を増加させる アンローリングなどの逐次高速化手法を、スレッド数に特化させる 2023年度 計算科学技術特論A
ハイブリッドMPI/OpenMP実行の注意点 (その3) 通信処理の時間に含まれる、データのコピー時間が、 通信時間よりも大きいことがある 問題空間の配列から送信用の配列にコピーする処理 (パッキング) 受信用の配列から問題空間の配列へコピーする処理 (アンパッキング) 上記のコピー量が多い場合、コピー操作自体もOpenMP化 すると高速化される場合がある。 特に、強スケーリング時 問題サイズやハードウェアによっては、OpenMP化すると遅くなる。 このときは、逐次処理にしないといけない。 パッキング、アンパッキングをOpenMP化する/しない、も ハイブリッドMPI実行では重要なチューニング項目になる 69 2023年度 計算科学技術特論A
ハイブリッドMPI/OpenMPの起動方法 スパコンごとに異なるが、以下の方法が主流 (すでに説明済み)。 1. 2. ccNUMAの場合、MPIプロセスの割り当てを、期待する 物理ソケットに割り当てないと、ハイブリッドMPI実行の 効果が無くなる 70 バッチジョブシステムを通して、MPIの数を指定 実行コマンドで、OMP_NUM_THREADS環境変数で スレッド数を指定 Linuxでは、numactlコマンドで実行時に指定する (ただし多くのスパコンでは指定不要) スパコン環境によっては、プロセスを指定する物理コアに 割り当てる方法がある。 (各スパコンの利用マニュアルを参考) 2023年度 計算科学技術特論A
数値計算ライブラリとハイブリットMPI実行 数値計算ライブラリのなかには、ハイブリッドMPI実行を サポートしているものがある 数値計算ライブラリがスレッド並列化されている場合 特に、密行列用ライブラリのScaLAPACKは通常、 ハイブリッドMPI実行をサポート ScaLAPACKは、MPI実行をサポート ScaLAPACKは、LAPACKをもとに構築 LAPACKは基本数値計算ライブラリBLASをもとに構築 BLASは、スレッド実行をサポート ⇒BLASのスレッド実行と、ScaLAPACKのMPI実行を基にした ハイブリッドMPI実行が可能 71 2023年度 計算科学技術特論A
スレッド並列版BLAS利用の注意 BLASライブラリは、OpenMPスレッド並列化がされている 利用方法は、OpenMPを用いた並列化と同じ OMP_NUM_THREADSで並列度を指定 BLASで利用するスレッド数が利用可能なコア数を超えると 動かないか、動いたとしても速度が劇的に低下する BLASを呼び出す先がスレッド並列化をしている場合、BLAS内で スレッド並列化をすると、総合的なスレッド数が、利用可能な コア数を超えることがある。このため、速度が劇的に低下する。 一般的に、逐次実行の演算効率が、 OpenMPスレッド並列の実行効率に比べて、高い 72 上位のループをOpenMPスレッド並列化し、そのループから 逐次BLASを呼び出す実装がよい 2023年度 計算科学技術特論A
逐次BLASをスレッド並列化して呼び出す例 通常のBLASの呼び出し do i=1, Ak call dgemm(…) ←スレッド並列版BLASを呼び出し (コンパイラオプションで指定) enddo 上位のループでOpenMP並列化したBLASの呼び出し !$omp parallel do do i=1, Ak call dgemm(…) ←逐次BLASを呼び出し (コンパイラオプションで指定) enddo !$omp end parallel do 73 2023年度 計算科学技術特論A
<スレッド並列版BLAS>と<逐次BLASを上位の ループでスレッド並列呼び出し>する時の性能例 T2Kオープンスパコン(東大版) AMD Quad Core Opteron 1ノード(16コア)を利用 日立製作所によるCコンパイラ(日立最適化C) OpenMP並列化を行った BLAS GOTO BLAS ver.1.26 (スレッド並列版,および遂次版の双方) 対象処理 74 最適化オプション:“-Os -omp” 高精度行列‐行列積の主計算 複数の行列‐行列積(dgemm呼び出し)を行う部分 2023年度 計算科学技術特論A
n=1000での性能( T2K(1ノード, 16コア)) BLAS内でスレッド並列化する場合に対する速度向上 [速度向上] 4.5 4 3.86 3.5 3.80 3.84 3.59 3.44 3 2.64 2.5 2.59 2.32 1.80 2 1.5 1 3.79 3.50 スレッド並列版BLASに 対する速度向上 1.97 1.77 3.53 3.78 8スレッドを超えると 約3.8倍の速度向上! 0.81 0.5 [スレッド数] 0 75 1 2 3 4 5 6 7 8 2023年度 9 10 11 計算科学技術特論A 12 13 14 15 16
ScaLAPACKにおけるハイブリッドMPI 実行 ScaLAPACKは、MPI化されており、LAPACKを 利用している LAPACKは、BLASを利用している BLASは、逐次版とスレッド並列版がある ⇒BLASにスレッド並列版を利用することで、 ScaLAPACKは、簡単にハイブリッドMPI/OpenMP 実行ができる 76 ただし、MPIスレッド数(プロセッサーグリッド)、と OpenMPスレッド数のチューニングが必須 2023年度 計算科学技術特論A
コンパイラ最適化の影響(その1) MPI化、および、OpenMP化に際して、ループ構造を 逐次から変更することになる この時、コンパイラに依存し、コード最適化が並列ループ に対して、効かない(遅い)コードを生成することがある 上記の場合、逐次実行での効率に対して、並列実行で の効率が低下し、台数効果の向上を制限する たとえば、ループ変数に大域変数を記載すると、 コンパイラの最適化を阻害することがある 77 特に並列処理制御変数である、全体のMPIプロセス数を 管理する変数、自分のランク番号を管理する変数は、 大域変数であることが多いので注意。 2023年度 計算科学技術特論A
コンパイラ最適化の影響(その2) MPI並列コードで、ループに大域変数を使っている例 C言語の例 Fortran言語の例 ib = n/numprocs; for( j= myid * ib; j<(myid+1) * ib; j++) { y[ j ] = 0.0; for(i=0; i<n; i++) { y[ j ] += A[ j ][ i ] * x[ i ]; } } ib = n/numprocs do j = 1 + myid * ib, (myid+1) * ib y( j ) = 0.0d0 do i=1, n y( j ) = y( j ) + A( j, i ) * x( i ) enddo enddo 上記のmyidは大域変数で、自ランク番号を記憶している変数 コンパイラがループ特徴を把握できず、最適化を制限 ←逐次コードに対して、演算効率が低下し、台数効果を制限 解決策:局所変数を宣言しmyidを代入。対象を関数化。 78 2023年度 計算科学技術特論A
ハイブリッドMPIプログラミングのまとめ ノード数が増えるほど、ピュアMPI実行に対する効果が増加 経験的には、1000MPIプロセスを超える実行で、 ハイブリッドMPI実行が有効となる 現状での効果はアプリケーションに依存するが、 経験的には数倍(2~3倍)高速化される 現在、多くの実例がある 現在主流の10万並列を超える超並列実行環境では、 おそらく数十倍の効果がある ノードあたりの問題サイズが小さいほど、 ハイブリッドMPI実行の効果が増大 79 弱スケーリングより強スケーリングのほうが ハイブリッドMPI実行の効果がある 2023年度 計算科学技術特論A
レポート課題(その1) 問題レベルを以下に設定 問題のレベルに関する記述: •L00: きわめて簡単な問題。 •L10: ちょっと考えればわかる問題。 •L20: 標準的な問題。 •L30: 数時間程度必要とする問題。 •L40: 数週間程度必要とする問題。複雑な実装を必要とする。 •L50: 数か月程度必要とする問題。未解決問題を含む。 ※L40以上は、論文を出版するに値する問題。 教科書のサンプルプログラムは以下が利用可能 Samples-fx.tar Mat-Vec-fx.tar PowM-fx.tar Mat-Mat-fx.tar Mat-Mat-d-fx.tar LU-fx.tar 80 2023年度 計算科学技術特論A
レポート課題(その2) [L20] 使える並列計算機環境で、教科書の サンプルプログラムを並列化したうえで、 ピュアMPI実行、および、ハイブリッドMPI実行で 性能が異なるか、実験環境(たとえば、12ノード、384コア) を駆使して、性能評価せよ。 1. 81 1ノードあたり、12MPI実行、1MPI+32スレッド実行、2MPI+16スレッド 実行、4MPI+8スレッド実行など、組み合わせが多くある。 2023年度 計算科学技術特論A
レポート課題(その3) 2. 3. [L10] ハイブリッドMPI実行がピュアMPI実行に対して有効と なるアプリケーションを、論文等で調べよ。 [L20~] 自分が持っている問題に対し、ハイブリッドMPI実 行ができるようにプログラムを作成せよ。また、実験環境を 用いて、性能評価を行え。 82 2023年度 計算科学技術特論A