4.7 富士通スパコン

4.7.1 Fujitsu Supercomputer PRIMEHPC

Fujitsu Supercomputer PRIMEHPC FX700 [7](以下、FX)を用いた高速化について述べます。
図4-7-1にFX700の仕様を示します。
FXのCPUは48コアから成り、それぞれ512ビットのSIMDベクトル演算を行うことができます。
内側のループをコンパイラーの自動ベクトル化によってSIMDベクトル計算し、 外側のループをOpenMPによって並列計算します。
さらに複数のノードで計算するには領域分割を行いMPIを用いて並列計算します。
本プログラムは前節まででOpenMPとMPIによって並列化されていますので、FXに対応することは比較的容易です。
ただしベクトル化するために余分な配列が必要になり必要メモリーは12/5=2.4倍になります。

4.7.2 FXの計算時間

表4-7-1にFXの計算時間を示します。
表より全コアをOpenMPで並列計算するよりもMPIで4プロセスに分割したほうが大幅に速く計算できることががわかります。 これは図4-7-2のブロック図と関係すると思われます。

表4-7-1 FXの計算時間
(FUCUSスパコンXシステム)
並列計算手法ベンチマーク300ベンチマーク400ベンチマーク500
1OpenMP 48スレッド 96.8秒229.8秒287.7秒
2OpenMP 12スレッド x MPI 4プロセス15.7秒 36.8秒 60.7秒

4.7.3 コンパイルメッセージ

リスト4-7-1に計算の主要部のコンパイルメッセージを示します。
コンパイルオプションに"-D_VECTOR"が必要です。
これから、一番外側のループがOpenMPで並列計算され、 一番内側のループがベクトル長16(=512ビット/単精度32ビット)でベクトル計算されることがわかります。
富士通スパコンの注意点は以下の通りです。

  1. マクロ"__FUJITSU"が定義されている。
  2. ベクトル化するループのindexは局所変数にする。
  3. ベクトル化するループのindexは64ビット整数にする。
  4. ベクトル化できないループを強制的にベクトル化するにはループの直前に制御文"#pragma loop novrec"を代入する。 このときコンパイルオプション"-Kocl"が必要。
  5. 一番内側のループではなるべくif文を使わない。

リスト4-7-1 計算の主要部(updateEx.c)のコンパイルメッセージ



$ fcc -c -D_VECTOR -Kfast,openmp,ocl,optmsg=2 -I../include -Nlst=t updateEx.c
$ cat updateEx.lst
Fujitsu C/C++ Version 4.0.0   Wed May 27 10:11:42 2020
(line-no.)(optimize)
        1             #include "ofd.h"
        2
        3             void updateEx_f(void)
        4             {
        5               const int64_t kmin = kMin;
        6               const int64_t kmax = kMax;
        7
        8               int64_t i;
        9             #ifdef _OPENMP
       10             #pragma omp parallel for
       11             #endif
       12   p           for (        i = iMin; i <  iMax; i++) {
       13   p           for (int64_t j = jMin; j <= jMax; j++) {
       14   p                   int64_t n = NA(i, j, kmin);
       15   p                   int64_t n1 = n - Nj;
       16   p                   int64_t n2 = n - Nk;
       17   p                   float *ptr_ex = &Ex[n];
       18   p                   float *ptr_hy = &Hy[n];
       19   p                   float *ptr_hz = &Hz[n];
       20   p                   float *ptr_hym = &Hy[n2];
       21   p                   float *ptr_hzm = &Hz[n1];
       22   p                   float *ptr_k1ex = &K1Ex[n];
       23   p                   float *ptr_k2ex = &K2Ex[n];
       24   p                   float      ryn =  RYn[j];
       25   p                   float *ptr_rzn = &RZn[kmin];
       26             #ifdef __FUJITSU
       27             #pragma loop novrec
       28             #endif
                       <<< Loop-information Start >>>
                       <<<  [OPTIMIZATION]
                       <<<    SIMD(VL: 16)
                       <<<    SPILLS :
                       <<<      GENERAL   : SPILL 0  FILL 1
                       <<<      SIMD&FP   : SPILL 0  FILL 0
                       <<<      SCALABLE  : SPILL 0  FILL 0
                       <<<      PREDICATE : SPILL 0  FILL 0
                       <<< Loop-information  End >>>
       29   p      v            for (int64_t k = kmin; k <= kmax; k++) {
       30   p      v                    *ptr_ex = *ptr_k1ex * (*ptr_ex)
       31                                       + *ptr_k2ex * (      ryn * (*ptr_hz - *ptr_hzm)
       32                                                     - *ptr_rzn * (*ptr_hy - *ptr_hym));
       33   p      v                    ptr_ex++;
       34   p      v                    ptr_hy++;
       35   p      v                    ptr_hz++;
       36   p      v                    ptr_hym++;
       37   p      v                    ptr_hzm++;
       38   p      v                    ptr_k1ex++;
       39   p      v                    ptr_k2ex++;
       40   p      v                    ptr_rzn++;
       41   p      v            }
       42   p           }
       43   p           }
       44             }
Total prefetch num: 0
Optimization messages
  jwd6001s-i  "updateEx.c", line 29: ループ制御変数'k'のループをSIMD化しました。
  jwd8663o-i  "updateEx.c", line 29: ソフトウェアパイプライニングの効果がないループと判断したため、ソフトウェアパイプライニングを抑止しました。
  jwd8209o-i  "updateEx.c", line 30: 多項式の演算順序を変更しました。
Statistics information
  Option information
    Command line options : -c -D_VECTOR -Kfast,openmp,ocl,optmsg=2 -I../include -Nlst=t
    Effective options    : -g0 -mt -Qy -std=gnu11 -x- -O3 -Knoalias_const -Kalign_loops
(略)



図4-7-1 FX700の仕様 [7]


図4-7-2 A64FXのブロック図 (FX1000の場合、 https://pr.fujitsu.com/jp/news/2018/08/22-1.html )