- openmpi 大規模集団通信の高速化
TSUBAME3のOPAは1ノードに4つついておりますが、デフォルトでは2つしか使用されません。
以下のように明示的に4つ使うようにすることで、大規模なノード数の際のMPI_Alltoall()のような通信量の多い集団通信が高速化する場合があります。
特にGPU通信時に効果的です。
- wrap.sh
#!/bin/sh export NUM_HFIS_PER_NODE=4 if [ $((OMPI_COMM_WORLD_LOCAL_RANK%NUM_HFIS_PER_NODE)) == 0 ];then $* |
- ジョブスクリプト例(f_node=8、GPUDirectあり)
#!/bin/sh . /etc/profile.d/modules.sh mpirun -x PATH -x LD_LIBRARY_PATH -x PSM2_CUDA=1 -x PSM2_GPUDIRECT=1 -npernode 4 -np $((4*8)) ./wrap.sh ./a.out |
- openmpi p2p通信の高速化
複数のhfi(opa)をmultirail(束ねて使用)することによって、p2p通信が高速化される場合があります。
これはGPU通信ではあまり効果的ではないようですが、CPU通信では効果的のようです。
multirailを有効にするには以下のようにします。(openmpiの場合)
mpirun ... -x PSM2_MULTIRAIL=2 ... ./a.out |
また、multirail使用時のp2p通信のパフォーマンスはPSM2_MQ_RNDV_HFI_WINDOW(デフォルト値:131072、最大値:4MB)の値に依存するようです。
各パラメータの詳細な説明はこちらをご参照下さい。
- 1ノード内GPU通信について
TSUBAME3では1ノード内に4つのP100がついておりそれぞれNVLinkで接続されておりますが、ハードウェア構成の図にあります通りGPU0<->GPU2とGPU1<->GPU3間はNVLinkが2本で接続されており帯域幅が倍になっております。
可能であるならばこれらのGPU間で通信させるようにするとプログラムが高速化されるかもしれません。
※h_nodeではGPU0,1またはGPU2,3のみ確保されますので、これはf_nodeでしかできません。
- openmpi関連のtips
* 出力にランク番号を表示させたい場合
mpirun -tag-output ... |
* 集団通信のアルゴリズムを明示的に指定したい場合(デフォルトではMPIが動的にコミュニケータサイズ・メッセージサイズからアルゴリズムが選択されます)
例、MPI_Allreduce()の場合
mpirun -mca coll_tuned_use_dynamic_rules 1 -mca coll_tuned_allreduce_algorithm <algo #> ... |
アルゴリズムの番号はAllreduceの場合、1 basic linear, 2 nonoverlapping (tuned reduce + tuned bcast), 3 recursive doubling, 4 ring, 5 segmented ring
詳細は
ompi_info --param coll tuned --level 9 |
または
ompi_info -all |
で確認できます。
また、
mpirun -mca coll ^tuned |
とすると集団通信のtunedモジュールをdisableにしてbasicモジュールに切り替えることができます。
パフォーマンス的には下がりますが、tunedモジュールに問題が疑われる場合は有効です。
* mpirunからlaunchされるプロセスをqrsh -inherit ...経由でなくssh経由にする(f_nodeのみ)
mpirun -mca plm_rsh_disable_qrsh true -mca plm_rsh_agent ssh ... |
デフォルトだとqrsh -inherit経由でプロセスがlaunchされますが、それに起因する問題がある場合はこちらをお試し下さい。
* 現在の設定MCAパラメータ一覧を表示
mpirun -mca mpi_show_mca_params 1 ... |
また、MCAパラメータは以下のように環境変数を用いて渡すこともできます。
export OMPI_MCA_param_name=value |
nameが変数名、valueが値になります。
* openmpiを使用しているジョブでsegmentation faultが発生した際にコアファイルを取得
openmpiでsegmentation fault等でコアを取得したい場合、ジョブスクリプト内部でulimit -c unlimitedとしても取得されないようです。
以下のようにラップするようにするとコアファイルが取得できますので、コアファイルが必要な場合にはお試し下さい。
- ulimit.sh
#!/bin/sh ulimit -c unlimited |
mpirun ... ./ulimit.sh ./a.out |
* CPU binding関連
openmpiでのCPU binding関連のオプションは以下になります。
mpirun -bind-to <core, socket, numa, board, etc> ... mpirun -map-by <foo> ... |
詳細はman mpirunをご参照下さい。
実際のbindingを確認したい場合は以下です。
mpirun -report-bindings ... |
- その他のtips
* GPUDirectのsend側の閾値
GPUDirectのsend側の閾値はデフォルトでは30000bytesとなっております.
recv側はUINT_MAX(2^32-1)なので、バッファサイズが大きい時にもsend側でもGPUDirectを常にONにしたければ以下のようにして下さい。
mpirun -x PSM2_GPUDIRECT_SEND_THRESH=$((2**32-1)) ... |
詳細はこちらをご参照下さい。