1 名前:デフォルトの名無しさん [04/11/07 18:25:56] MPIによる並列プログラミングについて話し合う統合スレッドです。 とりあえず本家 www-unix.mcs.anl.gov/mpi/
348 名前:デフォルトの名無しさん [2009/07/06(月) 06:59:07 ] MPIの本を読むとSendとReceiveって奇数ノードと偶数ノードそれぞれ順序を逆にして書かないとデッドロックが発生するようなのですが、 今まで、すべてのノードでSendを先に書いていたのですが、とくにデッドロックしたことはありません。 OSか何かに依存するのでしょうか?
349 名前:デフォルトの名無しさん mailto:sage [2009/07/06(月) 21:10:54 ] MPI_SendとMPI_Recvは送受信が完了するまで戻ってきませんが。 MPIの仕様なのでOSには依存しません。 別に偶数ノードと奇数ノードとか関係ありません。 送信と受信が対になって実行されないといけないだけです。 ノンブロッキング通信なら送信、受信動作が完了しなくても戻ってきますが、 別の関数で送受信が完了しているか確認をとる必要があります。
350 名前:デフォルトの名無しさん mailto:sage [2009/07/06(月) 21:46:09 ] >>348 どの本のどういう記述よ
351 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 14:04:08 ] そういえば、標準モードでMPIが勝手にバッファリングモードを使用していたら対応する受信が起動ていなくても戻ってくるか。 そういう意味ではMPIの実装依存でデッドロックが起きていないということになるわな。
352 名前:デフォルトの名無しさん [2009/07/07(火) 16:32:14 ] n 行 n 列 の整数二次元配列 A(i, j) のうち、i = 1 の成分 (A(1, 1), A(1, 2), A(1, 3), ..., A(1, n-1), A(1, n)) だけを j = 1 から m 個ローカルプロセスの B(j) に集めたいと思います。 そこで、mpi_gather を使って以下のように書いたのですが、 このままでは m/n 個しか B(j) に渡されないようなのです。 call mpi_gather(A(1, 1), m, mpi_integer, B(1), m, mpi_integer, 0, mpi_comm_world, ierr) fortran で書いていますので、この原因がメモリ上でのデータの 並び方(データがメモリ上で A(1, 1), A(2, 1), A(3, 1), ..., A(n, 1), A(1, 2), ... と並ぶ)なのだろうと思いますが、もし 飛び飛びでデータを選ぶ(j だけ m 個 ローカルに渡す)方法を ご存じでしたら教えて頂けないでしょうか? 初心的な質問ですみません。
353 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 19:07:19 ] >>352 つ MPI_TYPE_VECTOR
354 名前:デフォルトの名無しさん [2009/07/07(火) 20:32:32 ] >> 353 神様、仏様、353様! 早速お教え頂きありがとうございました。
355 名前:デフォルトの名無しさん [2009/07/24(金) 16:46:11 ] MPICH2とOpenMPIを使い分ける基準ってなんなのだろう 構文の違いと通信のしかたの違いとでどういう特徴があるのか・・・
356 名前:355 [2009/07/24(金) 16:49:25 ] ちなみに自分のはMac OS XなのでOpenMPIが標準で入っているそうですが (XgridもOpenMPIを通して使うそうですね) MPICH2のほうはどうなのか、ちと気になりましてw
357 名前:デフォルトの名無しさん [2009/09/06(日) 10:48:01 ] mpif77 でコンパイルは出来るのですが、 実行時 に mpirun -np 4 tttt と入力すると error while loading shared libraries : libompi_f77.so.o cannot open云々 となって動きません。libにはあるんですが、どうしたらよいか教えて下さい
358 名前:デフォルトの名無しさん mailto:sage [2009/09/06(日) 11:37:43 ] >>357 実行時に .so ファイルを探したが見つからないというエラーなので適当な設定を加える必要がある。 libompi_f77.so のあるディレクトリを仮に /opt/lib とすると a) コンパイル時に -Wl,-rpath,/opt/lib オプションを指定する b) 実行時に環境変数 LD_LIBRARY_PATH=/opt/lib を設定する c) /etc/ld.so.conf に /opt/lib を追加して ldconfig コマンドを root 権限で実行する のどれかをすればいいと思われ。 a) は gcc のオプションで他のコンパイラにも同じようなオプションがある(はず)。 b) の環境変数の指定方法はあなたが使っているシェル(bash とか tcsh とか)によって違うので調べて。 c) は Linux の方法で、他の OS だとファイル名が違うかも知れない。
359 名前:デフォルトの名無しさん [2009/09/06(日) 13:37:28 ] サンプルプログラムを実行することができました。有難うございます
360 名前:デフォルトの名無しさん mailto:sage [2009/09/18(金) 16:07:43 ] rank数が0から始まるとちょっと使いにくいんですが、 勝手に include 'mpif.h' call mpi_init(ierr) call mpi_comm_rank(mpi_comm_world,np,ierr) call mpi_comm_size(mpi_comm_world,npe,ierr) np=np+1 ってやって使っても問題ないでしょうか?
361 名前:デフォルトの名無しさん mailto:sage [2009/09/18(金) 18:29:39 ] 好きにせぇや
362 名前:デフォルトの名無しさん mailto:sage [2009/09/19(土) 00:13:13 ] すいません、Visual studioのスレで聞いたんですが、 こっちで聞いた方が良いとのことでこっちにきました。 Visual studio2008+MPICH2+ifortranを使ってます。 ブレークポイントやステップ実行などが使いたいのですが、 デバッグ開始にすると「デバッグ情報が見つからないか、または一致しません」となります。 msdn.microsoft.com/ja-jp/library/ms164731.aspx 上のサイトにプロジェクトのプロパティのデバッグで[起動するデバッガ] を選択しろとありますが、 デバッガー-デバッガーの種類 しかそれらしいものが見当たらず、 また、グレーの文字になっていて変更できそうにありません(ネイティブのみとなっています) ちなみにデバッグなしで開始なら問題なく実行できますが… 今までCygwin上でwrite文を打ち込みながら原始的にやっていたので、 さっぱりVSの仕組みが分かっていなくて要領を得ないかと思うんですが、 どうすればデバッグモードで実行できるでしょうか?お手数ですが、アドバイスを頂くにあたって 足りない情報などあればご指摘ください。
363 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 17:43:11 ] >>362 VSスレの方がいいんじゃねーかな。 windowsでMPI使う物好きは少ないと思うし。 つーか、モロにVSの使い方だし。
364 名前:デフォルトの名無しさん mailto:sage [2009/10/13(火) 21:53:16 ] 質問です。fortranで配列の要素数をプロセス数に応じて決めたいのですが、 どのように宣言したらよいのでしょうか?allocateを使うしかないでしょうか? 77では無理ですか?
365 名前:デフォルトの名無しさん [2009/10/14(水) 11:12:10 ] call mpiplay(n) subroutine mpiplay(n) real data(n) とか、かな。Initializeやfinalizeはメイン階層でしてね。 もっとも今は77とそれ以降を混ぜて書いても解釈してくれるから allocate でがんがんやっても良いと思うけど。
366 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 19:51:56 ] >>365 なるほど。動的配列を使うまでもなくそれでいいのですか。 ありがとうございます。もう一つお聞きしたいのですが、 メインでもその配列を使いたいときはどうすればよいでしょう? rank等の取得の前に宣言部が来るのでそのやり方では出来ないでしょうか? ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか?
367 名前:365 [2009/10/15(木) 05:59:50 ] 365の例では サブルーチンでの型宣言 integer n とMPI呼出呪文w include 'mpif.h' が抜けてたね。 呪文はメイン階層でもする必要があるけど。 >>366 配列の要素数を、例えばプロセス数の100倍にしたければ、 program mpiwrapper (略;なんか行があったりなかったり) include 'mpif.h' (略、宣言部とか) call mpi_init(ierr) (略) call mpi_comm_size(mpi_comm_world,nprocs,ierr) n=nprocs*100 call mpiplay(n) (略) call mpi_finalize(ierr) stop end program mpiwrapper subroutine mpiplay(n) include 'mpif.h' integer n real data(n) (略) call mpi_comm_rank(mpi_comm_world,myrank,ierr) (略;分割対象のループがいっぱい。初期化とかiteration処理とか) (略その2;data配列をmainにお持ち帰りできないので書き出しとかはこの階層で) return end subroutine mpiplay かな?wrapperの表現が適切かはちと疑問だけど、まあここではOKということで・・・。 この例だと変数の初期値代入から書き出し保存などは全部 mpiplay(n)階層ですることになるね。
368 名前:デフォルトの名無しさん [2009/10/15(木) 06:29:09 ] そんなわけで、fortran77コンパチで且つ前もって配列サイズを決めなくて良い、というのは できるけど。めんどいよねw. 自分自身はコマンドラインの引数を使いたい、 計算コード自身は77で書いてしまった、の2つの理由で メイン階層のWrapperをCでつくる事が多いけど。上の例は良くつかう。 やはり、というか配列サイズが前もって決まっていないタイプのコードは 最適化が抑制されるのか、遅いね。まあいちいちコード編集&コンパイルの 手間がかからないから楽といえば楽だけど。
369 名前:デフォルトの名無しさん [2009/10/15(木) 06:37:31 ] だらだら書いてしまったけど・・・・ >>366 ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか? にYes!と書けば終わりだったな・・・・w 早起きはするものではないね。
370 名前:デフォルトの名無しさん mailto:sage [2009/10/17(土) 05:54:20 ] >>369 いえ、結構怪しかったんで具体的に書いてもらって助かります。 丁寧に教えてくれてありがとう。
371 名前:デフォルトの名無しさん mailto:sage [2009/10/17(土) 20:52:34 ] すみません、もう一つ質問なんですが、 vel(3,m) pos(3,m) (それぞれm番目の分子のxyz座標の速度と位置)を buffer(6,n) 1~3に速度(vel)を、4~6に位置(pos)をというように一つのbufferに詰め込んで 別のプロセスに送りたいんですけど、一回のアクセスで送り先のvel,pos両方に 格納することって出来ますか?別々にやらないとだめでしょうか? それとも受信用の配列(rbuffer(6,n))とか用意して、別の処理で受信用bufferから vel,posにそれぞれ移し替える方がよいでしょうか? ちなみに送られる分子のmは不連続なので送る過程ではbufferに詰め込んでますが、 送り先では送り先にある最大の分子の番号の末尾から連続で入れればよし、というような状況です。 (送り先に既にm個あったらm+1~m+nまで) 基本的に通信回数は減らした方がパフォは上がるという認識で良いですよね?
372 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 05:40:13 ] ・・・ラグランジュ法的な粒子なのね。 隣接関係(最近接の粒子番地)がころころかわるから厄介そう。 前半最後の2行が王道だとおもう。型の同じ変数は一つの配列名のに付けてから一度に送受信。 いっそ、最初からvelpos(6,m)みたいに位置や速度の情報を一つの大きめの配列にまとめちゃう方が いいかもね。vi(m) とか sed だと、 1,$s/pos(1/velposi(4/g 1,$s/pos(m/velposi(3+m/g みたいな感じでわりと一括置換が効きやすそうだし。 ・・・・・恐いけどw
373 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 06:45:10 ] >>372 うーん、やっぱそうですか。たびたびありがとうございます。 ちなみに代入はf90が使える場面なら PV(1:3,m+1:m+nmbuf)=rbuffer(1:3,1:nmbuf) PP(4:6,m+1:m+nmbuf)=rbuffer(4:6,1:nmbuf) みたいにループ使わずに書く方が速度的にもいいですか? (上であってます?間違いや冗長なところありますかね?) 上は簡略化してるんですが、実はもう少し複雑なので あまりパフォが違わないなら慣れた添え字ループの代入が無難かな。 情けない話ですが出来る限りコマンドラインを避けてるのでviとかsedとかの話あまり分かりません。 でもそれで置換出来るならプログラム書く効率あがりそうですね。覚えた方がいいと思いつつ… 統合環境がそういう複雑な置換装備してくれたらいいのにな。甘えすぎですか。
374 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 09:38:00 ] >>373 例では第一添え字が6要素だから、 do i=1,nmbuf pv(1:3,m+i) = rbuffer(1:3,i) pp(1:3,m+i) = rbuffer(4:6,i) enddo にするといいかな? 右側の要素を:つかって範囲指定すると遅くなることが多い・・・とおもう。 実装にも依存するけど、ベクトル的表現は第一添字(右端)だけに しておくのが安全&安心。 エディタでの一括置換は楽だけど諸刃の剣w
375 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 09:39:35 ] 第一添字(右端) ↓ 第一添字(左端)
376 名前:デフォルトの名無しさん [2009/10/20(火) 06:46:25 ] インテルコンパイラだけど、MPI使うには、インテルの売ってるやつを使わないといけないの?
377 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 22:03:31 ] 何でもええ。 ライブラリがリンクできれば。
378 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 02:41:08 ] MPI はコンパイラもだけど mpirun がないと。 自宅で文法チェックするだけなら -I -L
379 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 02:52:21 ] max plunk institute !
380 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 06:45:10 ] >>374 遅くなったけど本当にどうもありがとう。うまくできました。 ロードバランス大して考えずに領域の広さを均等にぶった切ったけどcore2quadで 3倍強の加速率でした。動的に負荷を割り振ったらもう少し早くなりそうかな?
381 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 20:05:53 ] 最近HyperThreading対応の4coreのCPUが家庭向けの値段まで落ちてきたので 購入したのだが、ここまでスレッド数が多くなるとメモリ帯域か何かが溢れて 評価しないと使えないな。 同じプログラムが、 Pentium4 2.8GHz(1core * 2スレッド)ではMPIで2プロセス走らせると1.6倍ぐらい速くなったけど、 Corei7-860(4core * 2スレッド)ではMPIで8プロセス走らせると4プロセスに比べて0.9倍 ぐらいに遅くなったよ。
382 名前:デフォルトの名無しさん [2009/10/26(月) 06:36:28 ] core i7か・・・いいな。このお金持ちめw いくらだった? 1 thread あたりの作業量は 4つの時に比べて0.9*4/8=45%くらいの残念くんだった、って事? 職場での印象では mpirun がメモリアクセスのスケジューリングを うまくさばいてくれていないような気はしたな。気がしただけで検証もなにもしてないけど。 やはり分散メモリのシステムとは根本的に違う、という事なのだろうな。 ・・・・OpenMPだともう少しマシな数字がでてくるのかな?
383 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 06:42:32 ] >>381 CPU とプロセス(またはスレッド)のアフィニティはどうしてる? プロセス数が多くなればなるほど、きっちり固定してやらないと パフォーマンス低下の原因になる希ガス。
384 名前:382 mailto:sage [2009/10/26(月) 07:00:00 ] OpenMPはデフォだとうろうろするのは知ってたけど。 MPIも固定しないのか・・・知らんかった・・・。
385 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 09:46:19 ] windowsだとOSがウロウロさせるんだけど。 高負荷のシングルスレッドを実行させると全CPUが12%程度になるよ(8core)。 LinuxでもたまにCPUを乗り換えるけどwindowsほど頻繁じゃない。
386 名前:381 mailto:sage [2009/10/26(月) 23:47:19 ] ふと4とか8プロセスとかとか切りのよい数字じゃなくて5とか6プロセスで 実行したらどうなるんだろうと思った。 現在1〜8プロセスの全てのパターンをベンチ中。多分終わるのは明日。 > core i7か・・・いいな。このお金持ちめw いくらだった? 再利用などしたので、マザボとメモリとCPUしか買ってませんが、46,675円 > 1 thread あたりの作業量は 4つの時に比べて0.9*4/8=45%くらいの残念くんだった、って事? そういう事です。 > CPU とプロセス(またはスレッド)のアフィニティはどうしてる? そのあたり詳しくないのでほとんど設定変更せず使ってます。 ちなみにOpenMPI/CentOS5.4です。
387 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 16:27:05 ] Pentium4ほどパイプラインがスカスカじゃないからHTの効能はあまりないんじゃないかな。 マルチ「スレッド」のプログラムならメモリ資源などの共用が多くHTの効果がでるかもしれないけど、 マルチ「プロセス」のMPIじゃ同一コアでキャッシュとメモリ帯域の争奪戦をするだけで効率低下すると思うけど。
388 名前:デフォルトの名無しさん [2009/10/28(水) 02:43:34 ] Visual C++2008でMPIを使いたいのですが、何をインストールすればよいのでしょうか?
389 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:57:18 ] HTは結局コアが4つしかないから、メモリ転送がネックになる場合だと、パフォーマンスが落ちるよ。 アフィニティで固定したとしても、論理コアが物理コアとリンクしているとは限らないだろうから、 コア間で依存性があった場合は注意が必要だと思う。 HTは簡単に言うと、あいているパイプラインを有効に使うことだから、2つの処理を同じコアで計算させていることだからね。 ただ、3次キャッシュが大きいので、コアが増えることでプリフェッチの恩恵は受けやすくなるかも。
390 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:59:50 ] >>384 そりゃそうでしょ。MPIだってコアの指定をしないとだめ。 もちろんPthreadでも。
391 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 03:24:38 ] いわれるとそりゃそうだわ、なんだけど 383のを見るまで気づかんかったw OpenMPだと dplace や taskset で固定できるけど、 これはハードベンダが作った奴だしねぇ。MPIで固定するのはどうするの(特にWin機)?