14. ベクトル計算

14.1 ベクトル計算とは

FOCUSスパコン[23]に導入されたNEC SX-Aurora TSUBASA[24]を用いたベクトル計算について述べます。
ベクトル計算とは長いfor文を長いベクトル長(ここでは256)を持ったVE(Vector Engine)で一括処理するものです。 またOpenMPを用いて並列計算するとさらに高速化されます。
プログラミングはXeonPhiとほぼ同じであり、 OpenMPによって並列化されており、かつアルゴリズムがベクトル化可能であれば、 コンパイラーの自動ベクトル化機能によってコンパイルするだけで高い性能を得ることができます。
また、XeonPhiと異なり、ホストとコプロセッサーの区別が不要ですので操作性に優れています。
本章では5.のOpenMPと同じソースコード(omp.c)を使用します。
使い方の詳細については「ユーザーズガイド」を参考にしてください。 なお、OSはLinuxです。

14.2 コンパイル・リンク方法

FOCUSスパコンでコンパイル・リンクする方法は以下の通りです。
> ssh fvpu1 (当該マシンにloginする)
> module load PrgEnv-nec (開発環境をロードする)
> ncc -O3 -fopenmp omp.c -o omp_ve (コンパイル・リンク)
Cコンパイラーのコマンドはnccです(C++はnc++)。 コンパイルオプションとリンクオプションは特に必要ありません。
コンパイルを行うと以下のようにベクトル化と並列化の情報が表示されます。 29行目と41行目のforループが並列化とベクトル化されていることがわかります。 コンパイルオプション"-fdiag-vector=2"を追加するとより詳細な情報が表示されます。

ncc: par(1801): omp.c, line 27: Parallel routine generated.: vadd$1
ncc: par(1801): omp.c, line 39: Parallel routine generated.: sdot$1
ncc: par(1803): omp.c, line 29: Parallelized by "for".
ncc: vec( 101): omp.c, line 29: Vectorized loop.
ncc: par(1803): omp.c, line 41: Parallelized by "for".
ncc: vec( 101): omp.c, line 41: Vectorized loop.
ncc: par(1809): omp.c, line 43: Barrier synchronization.
ncc: vec( 101): omp.c, line 80: Vectorized loop.
ncc: vec( 103): omp.c, line 96: Unvectorized loop.
ncc: vec( 101): omp.c, line 99: Vectorized loop.
ncc: vec( 103): omp.c, line 105: Unvectorized loop.

14.3 コンパイラ指示行

コンパイラ指示行によってコンパイルを調整することができます。 例えば自動ベクトル化できないfor文がベクトル化できることがあります。
コンパイラ指示行の書式は以下の通りです。
#pragma _NEC directive

14.4 マクロ演算

ベクトル化しにくい一部のアルゴリズム (例えば、配列の総和や内積を計算する、漸化式を計算する(a[i]=a[i-1]+b)など) はマクロ演算と呼ばれ、コンパイラーによって自動ベクトル化されます。

14.5 プログラムの実行方法

プログラムの実行方法は以下の通りです。
> omp_ve {1|2} 配列の大きさ 繰り返し回数 スレッド数
例えば以下のようになります。
> omp_ve 1 1000000 1000 8 (ベクトルの和を計算するとき)
> omp_ve 2 1000000 1000 8 (ベクトルの内積を計算するとき)
繰り返し回数は計算時間の測定誤差を小さくするためです。
コア数が8なのでスレッド数8まで速くなります。

14.6 ベクトル和の計算時間

表14-1にベクトル和の計算時間を示します。
配列の大きさ(=N)と繰り返し回数(=L)の積は一定(=1011)です。従って全体の演算量は同じです。
No.2のとき最も並列計算の速度比が高くなっています。

表14-1 ベクトル和の計算時間(NEC SX-Aurora TSUBASA Type 10C、単精度、()内は1スレッドとの速度比)
No.配列の大きさN繰り返し回数L 1スレッド 2スレッド 4スレッド 8スレッド
1 10,000,000 10,000 5.64秒(1.0) 3.42秒(1.65) 2.02秒(2.79) 1.73秒(3.26)
2 1,000,000 100,000 4.80秒(1.0) 2.64秒(1.82) 1.66秒(2.89) 0.97秒(4.95)
3 100,000 1,000,000 5.85秒(1.0) 4.93秒(1.19) 3.98秒(1.47) 3.75秒(1.56)
4 10,000 10,000,00015.54秒(1.0)26.20秒(0.59)25.88秒(0.60)30.13秒(0.52)

14.7 ベクトル内積の計算時間

表14-2にベクトル内積の計算時間を示します。
配列の大きさ(=N)と繰り返し回数(=L)の積は一定(=1011)です。従って全体の演算量は同じです。
No.1のとき最も並列計算の速度比が高くなっています。
演算量は表13-1のXeonPhiの10倍です。 最も速いケース(No.1, 8スレッド)ではXeonPhiの5倍以上速くなっています(100GFlops相当)。

表14-2 ベクトル内積の計算時間(NEC SX-Aurora TSUBASA Type 10C、単精度、()内は1スレッドとの速度比)
No.配列の大きさN繰り返し回数L 1スレッド 2スレッド 4スレッド 8スレッド
1 10,000,000 10,000 4.91秒(1.0) 2.55秒(1.93) 1.52秒(3.23) 1.20秒(4.09)
2 1,000,000 100,000 5.01秒(1.0) 2.85秒(1.76) 1.96秒(2.56) 1.65秒(3.04)
3 100,000 1,000,000 6.89秒(1.0) 6.29秒(1.10) 7.05秒(0.98) 9.61秒(0.72)
4 10,000 10,000,00025.30秒(1.0)39.40秒(0.64)55.96秒(0.45)89.16秒(0.28)