SR8000/SR11000

ysd@KLab > SR8000/SR11000

SR11000でのOpenMP

そもそも使うためにはパーソナルコース1では無理、というオチがありますが。

並列数の変更

2つの方法があります。
環境変数を設定する方法
setenv OMP_NUM_THREADS n
プログラムで設定する方法。
#pragma omp parallel num_threads(n)
もしくは
omp_set_num_threads(n);

NQSの紹介

SR8000で動作させるときは任意に、SR11000で動作させるときは必須で、NQSを利用することができます。
システムとしては、キューに様々なユーザがジョブを投げて順に処理をしてくれることになります。メリットとしては完全に単独で実行されるので理論上最高速で動きます。デメリットとしてはノードが空いていない限り使えない(ので、場合によってはジョブを投げてから結果が返ってくるまで大分時間がかかる)ということと、インタラクティブな使い方(例えばデータ学習させるときに、状況を表示して人間がそれに該当する教師データを与える等)ができないことがあります。

使い方

以下ようなことを書いたファイル(ジョブファイル)を作ります。
#!/bin/csh 使用シェル
#@$-q mpp-lecture 投げるキューの名前
#@$-N 4 使用するノード数
#@q-J SS ジョブタイプ
#@$-o OUT 標準出力の出力先ファイル
#@$-e ERR 標準エラーの出力先ファイル
#@$-lT 00:10:00 制限時間
mpirun -n 4 -np 32 hoge これ以降は普通にコマンド列

SR8000関連

SR8000でpthreadを使うとき

コードの中で
#include <pthread.h>
と書くより前に
#define _PTHREADS_D10
と書く必要がある。やっていることは pthread のバージョン指定。

SR8000でのコンパイル(pthread編)

cc -Os +Op -noparallel -o hoge hoge.c -lpthreads -lc_r
でOK。最初の -Os は man によると
-O4 -loopfuse -loopsplit=2 -pvec -parallel=3 -coalescing -cyclic -syncreduce=2
-approx-dis-bracket -divmove -expmove
を設定して、実行時間が最短になるようにする最適化オプションだそうだ。
ちなみに次の +Op は man から読み取ると
If +Op is specified, compiler assumes that there is no dependency between each argument in the same invocation of function.
(参考訳)ある関数呼び出しにおける引数同士の間には依存がないことを仮定する
とのことらしい。これは具体例を挙げて説明しておこう。
int multiply(int* z[], int* x[], int* y[]){
  for( int i = 0 ; i < N ; i++ ) z[i] = x[i] * y[i];
}
ここで、x, y, z として確保されている領域(正確には読まれる領域と書き込む領域)が重複しないということを仮定するということです。つまりこの関数を呼び出す時に
ret = multiply(xx, xx, yy);
なんてことをしてはいないという仮定です。

SR8000での実行

prun -n 1 ./hoge
普通に実行しても実行できますが、上記のように実行すると、他者との競合を避け、1ノードを占有して実行してくれます。 結果的にずいぶん速くなります。