FOCUSスパコン[23]に導入されたFujitsu Supercomputer PRIMEHPC FX700[26](以下FX)について述べます。
FXは48個のコアによる並列計算と512ビットSIMDによるベクトル計算を用いて計算します。
アプリケーションが並列化とSIMDベクトル化に適したアルゴリズムであれば比較的容易な作業で高い性能を得ることができます。
FOCUSスパコンのXシステムの仕様は以下の通りです。
注意
現在は暫定運用なので本章の結果は今後修正する可能性があります。
詳しい仕様は下記の通りです。[26]
FOCUSスパコンのXシステムでコンパイル・リンクする方法は以下の通りです。
> fcc -Kfast,openmp -Nlibomp omp.c -o omp
デバッグ時は以下のようにします。
> fcc -Kfast,openmp,optmsg=2 -Nlibomp -Nlst=t omp.c -o omp
コンパイルオプション"-Koptmsg=2"をつけると最適化の状態が表示されます。
コンパイルオプション"-Nlst=t"をつけると標準出力ではなく.lstファイルに出力されます。
以下に.lstファイルの抜粋を示します。
(line-no.)(optimize) (略) 23 static inline void vadd(int n, const float a[], const float b[], float c[]) 24 { 25 int i; 26 #ifdef _OPENMP 27 #pragma omp parallel for 28 #endif <<< Loop-information Start >>> <<< [OPTIMIZATION] <<< SIMD(VL: 16) <<< Loop-information End >>> 29 p 2v for (i = 0; i < n; i++) { 30 p 2v c[i] = a[i] + b[i]; 31 p 2v } 32 } 33 34 static inline float sdot(int n, const float a[], const float b[]) 35 { 36 float sum = 0; 37 int i; 38 #ifdef _OPENMP 39 #pragma omp parallel for reduction(+:sum) 40 #endif <<< Loop-information Start >>> <<< [OPTIMIZATION] <<< SIMD(VL: 16) <<< SOFTWARE PIPELINING(IPC: 1.75, ITR: 384, MVE: 2) <<< Loop-information End >>> 41 p 8v for (i = 0; i < n; i++) { 42 p 8v sum += a[i] * b[i]; 43 p 8v } 44 45 return sum; 46 } (略) Optimization messages jwd6001s-i "omp.c", line 29: ループ制御変数'i'のループをSIMD化しました。 jwd8664o-i "omp.c", line 29: ループ内に関数呼出しなどの最適化対象外の命令があるため、ソフトウェアパイプライニングを適用できません。 jwd8202o-i "omp.c", line 29: このループを展開数2回でループアンローリングしました。 jwd6004s-i "omp.c", line 41: リダクション演算を含むループ制御変数'i'のループをSIMD化しました。 jwd8204o-i "omp.c", line 41: ループにソフトウェアパイプライニングを適用しました。 jwd8205o-i "omp.c", line 41: ループの繰返し数が384回以上の時、ソフトウェアパイプライニングを適用したループが実行時に選択されます。 jwd8208o-i "omp.c", line 42: ループ内の総和または乗積演算の計算方法を変更しました。 (略)
3通りで最適化の状態が出力されます。
FXでは48コアで並列計算するには、コンパイラの自動並列化を使用するか、
OpenMPの指示文を記入して並列化するかの2通りがあります。
コンパイルオプションとリンクオプションについては前者は"-Kparallel"、後者は"-Kopenmp"となります。
ソースコードに最適化制御行を記入することによってコンパイル時に最適化を制御することができます。
最適化制御行を有効にするにはコンパイルオプション"-Kocl"が必要です。
例えば自動でSIMDベクトル化できないfor文がSIMDベクトル化できることがあります。
最適化制御行の書式は以下の通りです。
#pragma loop directive
なお、富士通C/C++コンパイラーではマクロ"__FUJITSU"が定義されています。
プログラムの実行方法は以下の通りです。
> omp {1|2} 配列の大きさ 繰り返し回数 スレッド数
例えば以下のようになります。
> omp 1 10000000 10000 8 (ベクトルの和を計算するとき)
> omp 2 10000000 10000 8 (ベクトルの内積を計算するとき)
繰り返し回数は計算時間の測定誤差を小さくするためです。
表15-1にベクトル和の計算時間を示します。
配列の大きさ(=N)と繰り返し回数(=L)の積は一定(=1011)です。従って全体の演算量は同じです。
No.2のとき最も並列計算の速度比が高くなっています。
No.4で時間がかかるのはスレッドを多数回起動するオーバーヘッドと考えられます。
No. | 配列の大きさN | 繰り返し回数L | 1スレッド | 4スレッド | 16スレッド | 32スレッド | 48スレッド |
---|---|---|---|---|---|---|---|
1 | 10,000,000 | 10,000 | 25.24秒(1.0) | 9.03秒(2.79) | 13.14秒(1.92) | 13.28秒(1.90) | 15.17秒(1.66) |
2 | 1,000,000 | 100,000 | 25.89秒(1.0) | 7.62秒(3.40) | 2.88秒(8.99) | 2.63秒(9.84) | 2.75秒(9.41) |
3 | 100,000 | 1,000,000 | 26.35秒(1.0) | 14.92秒(1.77) | 13.09秒(2.01) | 17.25秒(1.53) | 20.16秒(1.31) |
4 | 10,000 | 10,000,000 | 39.27秒(1.0) | 79.84秒(0.49) | 118.46秒(0.33) | 149.83秒(0.26) | 342.51秒(0.11) |
表15-2にベクトル内積の計算時間を示します。
配列の大きさ(=N)と繰り返し回数(=L)の積は一定(=1011)です。従って全体の演算量は同じです。
No.2のとき最も並列計算の速度比が高くなっています。
No.4で時間がかかるのはスレッドを多数回起動するオーバーヘッドと考えられます。
No. | 配列の大きさN | 繰り返し回数L | 1スレッド | 4スレッド | 16スレッド | 32スレッド | 48スレッド |
---|---|---|---|---|---|---|---|
1 | 10,000,000 | 10,000 | 13.15秒(1.0) | 4.78秒(2.75) | 9.55秒(1.38) | 9.39秒(1.40) | 16.56秒(0.79) |
2 | 1,000,000 | 100,000 | 19.24秒(1.0) | 3.65秒(5.27) | 2.38秒(8.08) | 2.75秒(7.00) | 8.50秒(2.26) |
3 | 100,000 | 1,000,000 | 12.63秒(1.0) | 12.31秒(1.03) | 15.44秒(0.82) | 22.37秒(0.56) | 74.63秒(0.17) |
4 | 10,000 | 10,000,000 | 26.72秒(1.0) | 93.09秒(0.29) | 142.16秒(0.19) | 195.37秒(0.14) | 718.71秒(0.04) |
表15-3にMPIを使用した時のベクトル内積の計算時間を示します。
ソースコードは7.のsdot_mpi.cと同じです。
コンパイル方法は以下の通りです。
$ mpifcc -Kfast -DMPI sdot_mpi.c -o sdot_mpi配列の大きさ(=N)と繰り返し回数(=L)の積は一定(=1011)です。従って全体の演算量は同じです。
No. | 配列の大きさN | 繰り返し回数L | 1プロセス | 12プロセス | 24プロセス | 36プロセス |
---|---|---|---|---|---|---|
1 | 10,000,000 | 10,000 | 14.58秒(1.0) | 1.33秒(11.0) | 0.97秒(15.0) | 1.04秒(14.0) |
2 | 1,000,000 | 100,000 | 23.36秒(1.0) | 1.54秒(15.2) | 0.99秒(23.6) | 0.89秒(26.2) |
3 | 100,000 | 1,000,000 | 14.62秒(1.0) | 4.57秒( 3.2) | 4.70秒( 3.1) | 4.74秒( 3.1) |