150 likes | 451 Views
Scalability Tuning with MPI. 日本 SGI 株式会社. 概要. 性能向上のために ケーススタディ NOGAPS. 性能向上のために. コンパイルオプション -64 メモリクロスマッピングは64ビット版 libmpi で有効です。 MPI の通信状況を調べる 環境変数 MPI_STATS を設定してください。 または、 mpirun コマンドの引数として、 -stats -p “%g%h:” を指定してください。
E N D
Scalability Tuning with MPI 日本SGI株式会社
概要 • 性能向上のために • ケーススタディ • NOGAPS
性能向上のために • コンパイルオプション -64 • メモリクロスマッピングは64ビット版libmpiで有効です。 • MPI の通信状況を調べる • 環境変数 MPI_STATS を設定してください。 • または、 mpirun コマンドの引数として、 -stats -p “%g%h:”を指定してください。 • 環境変数MPI_BUFS_PER_PROCに32(デフォルト)以上の値を設定し、バッファリトライを低減してください。 • より多くのメモリが必要となります。
direct copy send/recv • 通信バンド幅を必要とするコードでは、 send/recvダイレクトコピーをお試しください。 • NUMAlinkでの MPI send/recv のバンド幅のピークは : • direct copy: 173 MB/sec on 250 MHz O2000 • buffered: 84 MB/sec on 250 MHz O2000 • direct copy: 280 MB/sec on O3000, shmem_getの最大のバンド幅 • all-to-all 通信やmany-to-many通信を行うコードに有効です。
direct copy send/recvの指定方法 • 環境変数 MPI_BUFFER_MAXに値Nを設定 • 次の条件を満たすとき、Nバイト以上のサイズのメッセージはダイレクトコピーで通信されます。 • MPI関数の仕様がバッファリングなし通信を許容 • -64でコンパイルされている。 • 送受信バッファがグローバルにアクセス可能なメモリ領域にアロケートされている。 • N=2000 の設定が多くの場合効果的 • 短いメッセージではあまり効果的ではない。 • 正しくダイレクトコピーが行われたかを通信状況で確認してください。
送受信バッファをグローバルにアクセス可能なメモリ領域にアロケートする送受信バッファをグローバルにアクセス可能なメモリ領域にアロケートする • 送信バッファを次のように指定する(どれか1つ): • 静的領域 (common blocks) • ヒープ領域 (SHPALLOCまたはshmallocでアロケート) • グローバルヒープ (f90のallocate文または環境変数SMA_GLOBAL_ALLOCを設定) • アロケータブル配列にSAVEの属性を指定するか、リターンする前にデアロケートする • SMA_GLOBAL_ALLOCを設定したときは、グローバルヒープサイズを大きくする必要があります。 環境変数SMA_GLOBAL_HEAP_SIZEを設定してください。
MPI get/put • レイテンシに影響されるコードではMPIの1方向通信(get/put)をお試しください。 • O3000 でのNUMAlinkのレイテンシ : • send/recv: 5 microsec • mpi_get: 1.5 microsec • もし、移植性を重視していなければ、 SHMEMを採用してください。 • shmem_get latency: 0.5 microsec
ケーススタディ –NOGAPSの例 • US Navyで開発された地球規模のスペクトル法による気象解析モデル • OriginでのMPIプログラムのスケーラビリティはあまり良くなかった。 • ベンチマーク時にSHMEMに書き換えた。 • 落札後、 SHMEM からMPI-2 get/put に書き換えた。 • ダイレクトコピーが有効な手段(SHMEM はバンド幅のためにはあまり使われず、レイテンシにのみ有効)
NOGAPSの性能SHMEM 対 MPIの1方向通信関数 Origin 2000, 250MHz R10k 48hr forecast T159L36
NOGAPSのMPI通信関数の性能 • 転置ルーチンをMPI get/put関数で置換 • T159L36 モデル12 hourの予測(60p)
O3000でのNOGAPS4の性能 • T159L24モデルのシミュレーション結果 • 転置部分にMPI-2の関数を使用、他はMPI-1の関数を使用
call shmem_barrier_all do 150 kk=1,lmtot ktag=ksendto(kk) call shmem_put8( y(1+(ktag-1)*len), x(1,ksnding(kk), len, ipsndto(kk) ) continue call shmem_barrier_all ltag=0 do 150 kk=1,lmtot ltag=ltag+1 ktag=ksendto(kk) call mpi_isend(x(1,ksnding(kk), len, mpireal, ipsndto(kk), ktag, mpicomm, iss(ltag), istat) ltag=ltag+1 ktag=krcving(kk) call mpi_irecv(y(1,krcving(kk), len, mpireal, iprcvfr(kk), ktag, mpicomm, iss(ltag), istat) 150 continue call mpi_wait_all(ltag,iss,istatm, istat) SHMEM vs. send/recvによる転置の比較
MPI_putによる転置 • common/buffer/ yg(length) • integer(kind=MPI_ADDRESS_KIND) winsize, target_disp • ! Setup: create a window for array yg since we will do puts into it • call MPI_type_extent(MPI_REAL8, isizereal8, ierr) • winsize=isizereal8*length • call MPI_win_create(yg, winsize, isizereal8, MPI_INFO_NULL, MPI_COMM_WORLD, iwin, ierr)
MPI_putによる転置(続き) • call mpi_barrier(MPI_COMM_WORLD,ierr) • do 150 kk=1,lmtot • ktag=ksendto(kk) • target_disp=(1+(ktag-1)*len)-1 • call mpi_put(x(1,ksnding(kk), len, MPI_REAL8, ipsndto(kk), target_disp, len, • MPI_REAL8, iwin, ierr) • 150 continue • call mpi_win_fence(0, iwin, ierr) • do kk=1,len*lmtot • y(kk)=yg(kk) • end do • ! Cleanup - destroy window • call mpi_barrier(MPI_COMM_WORLD,ierr) • call mpi_win_free(iwin, ierr)
まとめ • MPI の通信状況を確認してください。可能であれば、バッファリトライを低減してください. • 実行プロセッサ数が増えたとき、通信でどのくらいの時間を消費するのかを把握してください。 • send/recvダイレクトコピーをお試しください。 • レイテンシに影響されるコードであれば、 MPI-2またはSHMEMに書き換えてください。