トップページ⇒tech
500コメント204KB

Message Passing Interface (MPI) 統合スレ

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
MPIによる並列プログラミングについて話し合う統合スレッドです。

とりあえず本家
http://www-unix.mcs.anl.gov/mpi/

0322デフォルトの名無しさん2009/04/03(金) 12:07:03
>>321 MPI_ALLGATHERV
0323デフォルトの名無しさん2009/04/05(日) 04:03:40
お答え頂き有難うございます。ただ、ほとんど基本的なサブルーチンしか使ってないので
MPI_ALLGATHERVはよくわからないんですが、今見た感じだと受信バッファ内の
位置は指定しないといけないんですよね?とすると結局他のプロセスが持っている個数に
関してはこの通信の前に教えてやる必要があるということになるでしょうか?
0324デフォルトの名無しさん2009/04/05(日) 08:34:21
>>323 そうです。
0325デフォルトの名無しさん2009/04/05(日) 15:13:03
なるほど、大体分かりました。mpi_allgathervを使う場合、
num_molを個別に持たせる必要がある以外はほぼ上の形で書けそうですね。
mpi_allgathervなら送信バッファと受信バッファ個別に指定できるので
送信の開始アドレスをずらして指定して大丈夫なんですよね?

それと別の質問なんですが、mpich2をマルチコアcpu一個のマシンでで使う場合って
mpiconfigでホストのところに動かすマシンを追加するほかは特に設定いらないでしょうか?
あとは -np 4 をつけて実行するだけ?なんか単純な問題でも妙に遅いんですが…
キャッシュとかはCPU側で勝手に最適化して使ってくれてるんですかね?
0326デフォルトの名無しさん2009/04/06(月) 02:44:25
コード例を示したほうが良さげですね。こういう具合です。

int num_mol; // 各プロセスが持つ分子の数
double vel_mol[...]; // 分子の速度の配列。要素数は num_mol
int recvbuf_num_mol[NUM_PROCS];
int displs_vel_mol[NUM_PROCS];
double recvbuf_vel_mol[TOTAL_NUM_MOL];
// 1. まず各プロセスが自分の num_mol を他のプロセスに送る
// recvbuf_num_mol[i] にはランク i の num_mol が入る
MPI_Allgather(&num_mol, 1, MPI_INT, recvbuf_num_mol, 1, MPI_INT, MPI_COMM_WORLD);
// 2. recvbuf_num_mol から ALLGATHERV に必要な displs_vel_mol を作る
count = 0;
for (i = 0; i < NUM_PROCS; i++) {
displs_vel_mol[i] = count;
count = count + recv_num_mol[i];
}
// 3. 上記 1. で得た recvbuf_num_mol と 2. で得た displs_vel_mol を使って
// 各プロセスが自分の vel_mol (サイズ不定の配列) を他のプロセスに送る
MPI_Allgatherv (vel_mol, num_mol, MPI_DOUBLE, recvbuf_vel_mol, recvbuf_num_mol, displs_vel_mol, MPI_DOUBLE, MPI_COMM_WORLD);

マルチコアマシン1台で並列実行する場合は
-machinefile オプションに与えるファイルに localhost:4 のように記述するか
-machinefile オプションを使わずに mpirun -localonly 4 のように実行すると
良いような気がします。
0327デフォルトの名無しさん2009/04/08(水) 01:08:39
あるある
0328デフォルトの名無しさん2009/06/03(水) 17:15:01
PVMからMPIに鞍替えしようと思って勉強を始めようと思うのだが
今だとOpenMPIとMPICH2のどちらを勉強すればいいのだろう

Mac OS X LeopardにはOpenMPIがもれなくついてくるらしいのだが
MPICH2とどう特徴が異なるのかを見極めて判断したいのですが・・・
0329デフォルトの名無しさん2009/06/03(水) 23:59:12
>>328
MPIの実装に依存するようなプログラムでも作る気かい?
0330お願いします2009/06/18(木) 20:47:03
MPIでどうしてもわかりません。
f(x)=x*xの0~1の積分なんですが、答えが通常0.3333となるはずですが
なぜ以下のプログラムだと違った答えがでるのでしょうか?
すみません、どなたか教えていただけないでしょうか?
ちなみにプログラムはよくあるMPI(倍風館)の本のものです。
実行すると0.000488のような値がでてきます。困っています。
どうやれば0.3333みたいな値を得ることができるでしょうか?
0331お願いします2009/06/18(木) 20:53:12
#include <stdio.h>
#include <mpi.h>

main(int argc, char** argv) {
int my_rank; /* カレントプロセスのランク */
int p; /* プロセスの数 */
float a = 0.0; /* 全積分区間の左端 */
float b = 1.0; /* 全積分区間の右端 */
int n = 1024; /* 台形の全個数 */
float h; /* 台形の底辺の長さ */
float local_a; /* 本プロセスの積分区間の左端 */
float local_b; /* 本プロセスの積分区間の右端 */
int local_n; /* 本プロセスの台形の数 */
float integral; /* 本プロセスの積分 */
float total; /* 全積分値 */
int source; /* 積分を送るプロセス */
int dest = 0; /* すべてのメッセージは0へ */
0332お願いします2009/06/18(木) 20:53:55
int tag = 0;
MPI_Status status;

/* ローカルな積分を計算する */
float Trap(float local_a, float local_b, int local_n, float h);

/* MPIの初期化 */
MPI_Init(&argc, &argv);

/* カレントプロセスのランクを求める */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* プロセスの数を求める */
MPI_Comm_size(MPI_COMM_WORLD, &p);

h = (b-a)/n; /* hはすべてのプロセスで同じ */
local_n = n/p; /* したがって台形の数も同じ */

/* 各プロセスの積分区間の長さはlocal_n*hである。 */
/* 本区間は次から始まる */
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
integral = Trap(local_a, local_b, local_n, h);
0333お願いします2009/06/18(木) 20:54:39
/* 各プロセスの積分を加算する */
if (my_rank == 0) {
total = integral;
for (source = 1; source < p; source++) {
MPI_Recv(&integral, 1, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &status);
total = total + integral;
}
} else {
MPI_Send(&integral, 1, MPI_FLOAT, dest, tag, MPI_COMM_WORLD);
}

/* 結果のプリント */
if (my_rank == 0) {
printf("With n = %d trapezoids, our estimate\n", n);
printf("of the integral from %f to %f = %f\n", a, b, total);
}

/* MPIを閉じる */
MPI_Finalize();
} /* main */


0334お願いします2009/06/18(木) 20:55:45
float Trap(
float local_a /* 入力 */,
float local_b /* 入力 */,
int local_n /* 入力 */,
float h /* 入力 */){

float integral; /* 積分値 */
float x;
int i;

float f(float x); /* 被積分関数 */

integral = (f(local_a) + f(local_b))/2.0;
x = local_a;
for (i = 1; i <= local_n-1; i++) {
x = x + h;
integral = integral + f(x);
}
integral = integral*h;
return integral;
} /* Trap */

float f(float x) {
float return_val;
/* f(x) を計算する */
/* return_val に計算結果を入れる */
return_val = x * x;
return return_val;
} /* f */
0335お願いします2009/06/18(木) 20:57:04
これと一緒なんです。
http://tetralog.in/t/?date=20060118

本当よろしくお願いします。
0336デフォルトの名無しさん2009/06/19(金) 00:14:35
まず各ノードのintegralを送信せずに表示してみろよ。
積分が間違ってるのか送受信でやらかしてるのか区別つくだろ。
この程度のことくらいやってから他人に聞けば?
0337デフォルトの名無しさん2009/06/19(金) 14:08:34
>>330
手元で実行してみたが

$ mpirun -np 2 ./a.out
With n = 1024 trapezoids, our estimate
of the integral from 0.000000 to 1.000000 = 0.333333

となったぞ。ハードウェアの構成は何だ?
0338お願いします2009/06/19(金) 19:45:20
ありがとうございます。
PCクラスタ環境は

Fujitsu PRIMERGY RS200 ×16台
  Xeon 3.20GHz/L3:1MB ×2
  2GBメモリ
  146.8GB HDD ×2(RAID1利用のため実効はこの半分)
  73GB HDD ×5(RAID5利用のため実効はこの4/5)

こんな感じです。
0339お願いします2009/06/19(金) 20:10:05
見直したんですがやっぱり出てくる答えは0.000488になって正しくないです。
0340デフォルトの名無しさん2009/06/19(金) 21:01:54
>>339
だからよ、まずは積分単体が戻す答えを見て見ろっての。
どうせなにかの打ち間違いだろ。
0341デフォルトの名無しさん2009/06/19(金) 21:04:22
MPIがおかしいと思うなら、そんな積分した答えじゃなく、1とか単純な値を送信しろよ。
自分で問題切り分ける意思がゼロだな。
0342デフォルトの名無しさん2009/06/20(土) 04:41:49
本当にコピペしたコードそのままで打ち間違いが無いのなら、
まずはMPI部分を全部削って1CPUで動かしてみろよ。
0343お願いします2009/06/20(土) 12:43:17
MPI部分なしでやれば0.333でます
0344デフォルトの名無しさん2009/06/20(土) 18:44:42
Mac用のMPIはどこで手に入りますか?
0345デフォルトの名無しさん2009/06/20(土) 18:45:15
MacにはOpenMPIが入っているが
0346デフォルトの名無しさん2009/06/21(日) 07:22:30
通常のGigabitイーサネットとInfiniBandではMPIを使った際にどの程度差が出ますか?
もちろんプログラムにもよるでしょうが、InfiniBandに投資するだけの価値はありますか?
0347デフォルトの名無しさん2009/06/27(土) 19:20:41
>>346
自分のGigabit環境で、MPIプログラムの通信部分と演算部分の比率を出してみれば、
InfiniBand環境でどれくらい改善するか、予測が付くだろう。
あと、B/F値への要求が高いコードでは、マルチコア環境で、メモリアクセス速度により、
並列化効率がでない場合も多いので、この点も注意した方がいい。
0348デフォルトの名無しさん2009/07/06(月) 06:59:07
MPIの本を読むとSendとReceiveって奇数ノードと偶数ノードそれぞれ順序を逆にして書かないとデッドロックが発生するようなのですが、
今まで、すべてのノードでSendを先に書いていたのですが、とくにデッドロックしたことはありません。
OSか何かに依存するのでしょうか?
0349デフォルトの名無しさん2009/07/06(月) 21:10:54
MPI_SendとMPI_Recvは送受信が完了するまで戻ってきませんが。
MPIの仕様なのでOSには依存しません。

別に偶数ノードと奇数ノードとか関係ありません。
送信と受信が対になって実行されないといけないだけです。
ノンブロッキング通信なら送信、受信動作が完了しなくても戻ってきますが、
別の関数で送受信が完了しているか確認をとる必要があります。
0350デフォルトの名無しさん2009/07/06(月) 21:46:09
>>348
どの本のどういう記述よ
0351デフォルトの名無しさん2009/07/07(火) 14:04:08
そういえば、標準モードでMPIが勝手にバッファリングモードを使用していたら対応する受信が起動ていなくても戻ってくるか。
そういう意味ではMPIの実装依存でデッドロックが起きていないということになるわな。
0352デフォルトの名無しさん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 個 ローカルに渡す)方法を
ご存じでしたら教えて頂けないでしょうか?
初心的な質問ですみません。
0353デフォルトの名無しさん2009/07/07(火) 19:07:19
>>352
つ MPI_TYPE_VECTOR
0354デフォルトの名無しさん2009/07/07(火) 20:32:32
>> 353
神様、仏様、353様!
早速お教え頂きありがとうございました。
0355デフォルトの名無しさん2009/07/24(金) 16:46:11
MPICH2とOpenMPIを使い分ける基準ってなんなのだろう
構文の違いと通信のしかたの違いとでどういう特徴があるのか・・・
03563552009/07/24(金) 16:49:25
ちなみに自分のはMac OS XなのでOpenMPIが標準で入っているそうですが
(XgridもOpenMPIを通して使うそうですね)
MPICH2のほうはどうなのか、ちと気になりましてw
0357デフォルトの名無しさん2009/09/06(日) 10:48:01
mpif77 でコンパイルは出来るのですが、
実行時 に mpirun -np 4 tttt と入力すると
error while loading shared libraries : libompi_f77.so.o cannot open云々
となって動きません。libにはあるんですが、どうしたらよいか教えて下さい
0358デフォルトの名無しさん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 だとファイル名が違うかも知れない。
0359デフォルトの名無しさん2009/09/06(日) 13:37:28
サンプルプログラムを実行することができました。有難うございます
0360デフォルトの名無しさん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
ってやって使っても問題ないでしょうか?
0361デフォルトの名無しさん2009/09/18(金) 18:29:39
好きにせぇや
0362デフォルトの名無しさん2009/09/19(土) 00:13:13
すいません、Visual studioのスレで聞いたんですが、
こっちで聞いた方が良いとのことでこっちにきました。

Visual studio2008+MPICH2+ifortranを使ってます。
ブレークポイントやステップ実行などが使いたいのですが、
デバッグ開始にすると「デバッグ情報が見つからないか、または一致しません」となります。
http://msdn.microsoft.com/ja-jp/library/ms164731.aspx

上のサイトにプロジェクトのプロパティのデバッグで[起動するデバッガ] を選択しろとありますが、
デバッガー-デバッガーの種類 しかそれらしいものが見当たらず、
また、グレーの文字になっていて変更できそうにありません(ネイティブのみとなっています)
ちなみにデバッグなしで開始なら問題なく実行できますが…
今までCygwin上でwrite文を打ち込みながら原始的にやっていたので、
さっぱりVSの仕組みが分かっていなくて要領を得ないかと思うんですが、
どうすればデバッグモードで実行できるでしょうか?お手数ですが、アドバイスを頂くにあたって
足りない情報などあればご指摘ください。
0363デフォルトの名無しさん2009/09/24(木) 17:43:11
>>362
VSスレの方がいいんじゃねーかな。
windowsでMPI使う物好きは少ないと思うし。
つーか、モロにVSの使い方だし。
0364デフォルトの名無しさん2009/10/13(火) 21:53:16
質問です。fortranで配列の要素数をプロセス数に応じて決めたいのですが、
どのように宣言したらよいのでしょうか?allocateを使うしかないでしょうか?
77では無理ですか?
0365デフォルトの名無しさん2009/10/14(水) 11:12:10
call mpiplay(n)

subroutine mpiplay(n)
real data(n)


とか、かな。Initializeやfinalizeはメイン階層でしてね。

もっとも今は77とそれ以降を混ぜて書いても解釈してくれるから
allocate でがんがんやっても良いと思うけど。
0366デフォルトの名無しさん2009/10/14(水) 19:51:56
>>365
なるほど。動的配列を使うまでもなくそれでいいのですか。
ありがとうございます。もう一つお聞きしたいのですが、
メインでもその配列を使いたいときはどうすればよいでしょう?
rank等の取得の前に宣言部が来るのでそのやり方では出来ないでしょうか?
ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか?
03673652009/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)階層ですることになるね。
0368デフォルトの名無しさん2009/10/15(木) 06:29:09
そんなわけで、fortran77コンパチで且つ前もって配列サイズを決めなくて良い、というのは
できるけど。めんどいよねw. 自分自身はコマンドラインの引数を使いたい、
計算コード自身は77で書いてしまった、の2つの理由で
メイン階層のWrapperをCでつくる事が多いけど。上の例は良くつかう。

やはり、というか配列サイズが前もって決まっていないタイプのコードは
最適化が抑制されるのか、遅いね。まあいちいちコード編集&コンパイルの
手間がかからないから楽といえば楽だけど。
0369デフォルトの名無しさん2009/10/15(木) 06:37:31
だらだら書いてしまったけど・・・・
>>366 ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか?
にYes!と書けば終わりだったな・・・・w
早起きはするものではないね。
0370デフォルトの名無しさん2009/10/17(土) 05:54:20
>>369
いえ、結構怪しかったんで具体的に書いてもらって助かります。
丁寧に教えてくれてありがとう。
0371デフォルトの名無しさん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まで)
基本的に通信回数は減らした方がパフォは上がるという認識で良いですよね?
0372デフォルトの名無しさん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
0373デフォルトの名無しさん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とかの話あまり分かりません。
でもそれで置換出来るならプログラム書く効率あがりそうですね。覚えた方がいいと思いつつ…
統合環境がそういう複雑な置換装備してくれたらいいのにな。甘えすぎですか。
0374デフォルトの名無しさん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
0375デフォルトの名無しさん2009/10/18(日) 09:39:35
第一添字(右端)
↓
第一添字(左端)
0376デフォルトの名無しさん2009/10/20(火) 06:46:25
インテルコンパイラだけど、MPI使うには、インテルの売ってるやつを使わないといけないの?
0377デフォルトの名無しさん2009/10/20(火) 22:03:31
何でもええ。
ライブラリがリンクできれば。
0378デフォルトの名無しさん2009/10/21(水) 02:41:08
MPI はコンパイラもだけど mpirun がないと。
自宅で文法チェックするだけなら -I -L
0379デフォルトの名無しさん2009/10/22(木) 02:52:21
max plunk institute !
0380デフォルトの名無しさん2009/10/25(日) 06:45:10
>>374
遅くなったけど本当にどうもありがとう。うまくできました。
ロードバランス大して考えずに領域の広さを均等にぶった切ったけどcore2quadで
3倍強の加速率でした。動的に負荷を割り振ったらもう少し早くなりそうかな?
0381デフォルトの名無しさん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倍
ぐらいに遅くなったよ。
0382デフォルトの名無しさん2009/10/26(月) 06:36:28
core i7か・・・いいな。このお金持ちめw いくらだった?
1 thread あたりの作業量は 4つの時に比べて0.9*4/8=45%くらいの残念くんだった、って事?

職場での印象では mpirun がメモリアクセスのスケジューリングを
うまくさばいてくれていないような気はしたな。気がしただけで検証もなにもしてないけど。
やはり分散メモリのシステムとは根本的に違う、という事なのだろうな。
・・・・OpenMPだともう少しマシな数字がでてくるのかな?
0383デフォルトの名無しさん2009/10/26(月) 06:42:32
>>381
CPU とプロセス(またはスレッド)のアフィニティはどうしてる?
プロセス数が多くなればなるほど、きっちり固定してやらないと
パフォーマンス低下の原因になる希ガス。
03843822009/10/26(月) 07:00:00
OpenMPはデフォだとうろうろするのは知ってたけど。
MPIも固定しないのか・・・知らんかった・・・。
0385デフォルトの名無しさん2009/10/26(月) 09:46:19
windowsだとOSがウロウロさせるんだけど。
高負荷のシングルスレッドを実行させると全CPUが12%程度になるよ(8core)。
LinuxでもたまにCPUを乗り換えるけどwindowsほど頻繁じゃない。
03863812009/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です。
0387デフォルトの名無しさん2009/10/27(火) 16:27:05
Pentium4ほどパイプラインがスカスカじゃないからHTの効能はあまりないんじゃないかな。
マルチ「スレッド」のプログラムならメモリ資源などの共用が多くHTの効果がでるかもしれないけど、
マルチ「プロセス」のMPIじゃ同一コアでキャッシュとメモリ帯域の争奪戦をするだけで効率低下すると思うけど。
0388デフォルトの名無しさん2009/10/28(水) 02:43:34
Visual C++2008でMPIを使いたいのですが、何をインストールすればよいのでしょうか?
0389デフォルトの名無しさん2009/10/28(水) 02:57:18
HTは結局コアが4つしかないから、メモリ転送がネックになる場合だと、パフォーマンスが落ちるよ。
アフィニティで固定したとしても、論理コアが物理コアとリンクしているとは限らないだろうから、
コア間で依存性があった場合は注意が必要だと思う。
HTは簡単に言うと、あいているパイプラインを有効に使うことだから、2つの処理を同じコアで計算させていることだからね。
ただ、3次キャッシュが大きいので、コアが増えることでプリフェッチの恩恵は受けやすくなるかも。
0390デフォルトの名無しさん2009/10/28(水) 02:59:50
>>384
そりゃそうでしょ。MPIだってコアの指定をしないとだめ。
もちろんPthreadでも。
0391デフォルトの名無しさん2009/10/28(水) 03:24:38
いわれるとそりゃそうだわ、なんだけど
383のを見るまで気づかんかったw

OpenMPだと dplace や taskset で固定できるけど、
これはハードベンダが作った奴だしねぇ。MPIで固定するのはどうするの(特にWin機)?
03923812009/10/28(水) 21:52:47
>>386
悪禁になってしまったのだが結果だけかくと
5プロセスで走らせると最速のようです
0393デフォルトの名無しさん2009/10/29(木) 01:33:12
>>392
それだとメモリアクセスが一番のボトルネックじゃない?
ちょうど5コアでいい感じでメモリ帯域を食ってくれて、それ以下だと使い切れなくて、
それ以上だといっぱいになってしまう。
という感じに思える。
0394デフォルトの名無しさん2009/10/29(木) 03:41:16
そんな感じっぽいね。381氏の実験に感謝。

最近はベクトル化を意識してループを短くして,(メモリでかくなったから)配列に中間結果を格納して・・・
というのがスパコンでは流行、というか推奨されるけど、HTでは
ループ内での処理が冗長なベクトル化をあまり意識してないw古いタイプの
コードが並列化では利得が大きいかも・・という事なのかな。
いまはCacheも大きいからたいがいループ内が長くても収まるし。
0395デフォルトの名無しさん2009/12/04(金) 22:16:21
mpiの勉強を始めたばかりの者です。今、Bcastをやっていますが、どうにも解らなくなりました。ご指導ください。
使っているコンパイラー等はGfortran、open mpiです。解らなくなったのは、メインでBcastを使っても問題ないのですが、
サブルーチンでBcastを使うとエラーが発生してしまうんです。なんででしょうか?ちなみにプログラムは以下のとおりなんですが。
*
MPI 宣言文
*
IF(Nrank.EQ.0) NCP1=1000
CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr)
*
KKK = 100
NNN = NCP1 + Nrank*KKK
PRINT *, NNN
これは問題なく動きますが、
 IF(Nrank.eq.0) NCP1 = 1000
 CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr)
部分を IF(Nrank.EQ.0) CALL MAINSUBとし、サブルーチンを
 SUBROUTINE MAINSUB
IMPLICIT REAL*8(A-H,O-Z)
COMMON /ACTIVE/ NCP1
*
NCP1 = 1000
 CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr)
*
RETURN
END
として、コンパイルし実行すると、 1000、 100、200、300と画面に出力され、notice thatjob rank 1 with PID 4737...の
メッセージが表示されますが、何故か原因が解らないのです。よろしくお願いします。
0396デフォルトの名無しさん2009/12/04(金) 22:49:20
>>395
サブルーチンMAINSUBの中でmpif.hのインクルードしてる?
0397デフォルトの名無しさん2009/12/05(土) 07:53:23
395 ですがやっていません。やってみます。
0398デフォルトの名無しさん2009/12/05(土) 08:04:52
395 ですが、動きました。どうも有難うございます。
0399デフォルトの名無しさん2009/12/12(土) 13:25:37
WindowsでMPIをつこうたプログラムをコンパイルしたいのですが、
Windows XP+Vistal C++ 2008 Express以外に、どれをインストールすればよいのでしょうか?
0400デフォルトの名無しさん2009/12/12(土) 23:30:24
MPICH
0401デフォルトの名無しさん2009/12/20(日) 02:28:58
MPIってユーザーグループの会とか友の会とかないんですかね??
もしなかったら作ってみたいなっと思いまして.2ヶ月に一度くらい勉強会とかライトニングトークしあう的な規模のもので.
0402デフォルトの名無しさん2009/12/20(日) 11:22:07
あんなもん、一旦意味がわかればマニュアル見るだけでOKなので
2ヶ月に一度とかタルいことしてたら、次の勉強会までにプログラムできるようになっている。
てか、それでできない人間だけ集まっても意味ないし、できる人間は参加してもタルいだけだろう。
0403デフォルトの名無しさん2009/12/20(日) 11:52:25
プログラムのほとんどを1スレッドで走らせ、一部を並列計算させたい場合、
その一部以外を if(myrank==0) で囲えばいいの?
0404デフォルトの名無しさん2009/12/20(日) 13:09:48
うん、たいていそれでいいよ。

非並列処理部分の結果を並列部分で使いたい時だったら
ちゃんと伝達するのを忘れないように><
0405デフォルトの名無しさん2009/12/21(月) 05:10:55
ですよね
なんとなく「プログラムのほとんどが if 文」ってのが違和感なんだけど
他に書き方ないよね
0406デフォルトの名無しさん2009/12/21(月) 09:37:58
そうそう、なんかif (myrank .....が冗長に出てくるのがなんかイヤw
並列の出入口でやることが決まっていれば関数に押し込めるけど、そういう事ってあまり多くないし
引数受渡し部分でちょんぼすることあるし・・・><
0407デフォルトの名無しさん2009/12/23(水) 09:49:25
現在勉強中で、Send、Recvを使って簡単なプログラムを作って動かしていますが、送るデータの個数が
500以下だと問題なく送受でき、送受結果を画面に表示できるのですが、500個を超えると送受結果が
画面に表示できません。プログラムが暴走したような状態になってしまうんです。
データの型は倍精度浮動小数点なんですが、解決策は無いでしょうか?使用している
mpiは openmpiです。
0408デフォルトの名無しさん2009/12/23(水) 10:52:26
受信側のメモリを確保しているのかと3秒問いつめたい
0409デフォルトの名無しさん2009/12/23(水) 12:40:54
407ですが、受け側でも送り側と同じ配列だけメモリーは設定しております。
当初は配列をアロケートしていましたが、疑問に思い、配列を設定して
再コンパイルして実行しても同じなんですが。
0410デフォルトの名無しさん2009/12/23(水) 13:05:15
他人に自分の意志を伝えられない奴が
コンピュータに自分の意志を伝えるプログラミングができるわけがない。

ソースもなしに・・・エスパーも求もと書いとけ。
0411デフォルトの名無しさん2009/12/27(日) 20:24:15
openfabrics.orgがつながらない、、、
0412デフォルトの名無しさん2009/12/28(月) 22:57:30
先日、Bcastの件で指導を頂いたものですが、今回、ScatterとGatherについてご指導願います。
プログラムは
program TEST
  implicit real*8(a-h,o-z)
:
:   MPIの使用開始の手続き
:
dimension a(2000),b(2000)
!
if(Nrank.eq.0) then
do i=1, 2000
a(i)=dble(i)
enddo
endif
!
call MPI_Scatter(a(1),20,MPI_DOUBLE_Precision,b(1),20,0,MPI_COMM_WORLD,ierr)
!
if(Nrank.gt.0) then
do i=1, 20
print *,Nrank,b(i)  :この部分で画面に出力
enddo
endif
!
iiii = 1 + Nrank*10
call MPI_Gather(b(1),10,MPI=DOUBLE_Precision,a(iiii),10,MPI_DOUBLE_Precision,0,MPI_COMM_WORLD,ierr)
:
として、実行したのですが、画面出力部分では、出力値が全てのランクで0.0となるんです。
当然のことながらGatherでも同様なんですが、どうやった良いのか原因も何も解りません。どうかご指導ください


0413デフォルトの名無しさん2009/12/28(月) 23:06:52
失礼しました、
 Scatterで...,b(1),20,の後にMPI_DOUBLE_Precision,を書き漏らしております。
質問時の記入ミスです。すみません。
0414デフォルトの名無しさん2010/01/06(水) 09:09:27
これで出力が出ます。
それとGatherの方で
MPI=DOUBLE_Precision の=が_の間違い。
a(iiii)は、ランク0に送るなら
ランク0の受信バッファーを指定するので多分a(1)です。

implicit real*8(a-h,o-z)
include'mpif.h'
dimension a(2000),b(2000)
call mpi_init(ierr)
call mpi_comm_rank(mpi_comm_world,Nrank,ierr)
if(Nrank.eq.0) then
do i=1, 2000
a(i)=dble(i)
enddo
endif
call MPI_Scatter(a(1),20,MPI_DOUBLE_Precision,
& b(1),20,MPI_DOUBLE_Precision,
& 0,MPI_COMM_WORLD,ierr)
if(Nrank.gt.0) then
do i=1, 20
print *,Nrank,b(i)
enddo
endif
call mpi_finalize(ierr)
end
0415デフォルトの名無しさん2010/02/08(月) 17:39:36
PCだと大丈夫なんですが、大規模な計算機にジョブを投げたとき、
あるプロセスからの出力だけ途中で止まることがあります。
PCはintel fortran+mpich、大規模計算機はPGIfortran+Voltaire MPIです。

例えばプロセスごとにoutput00,output01,output02,output03のように
別のファイルに出力させているんですが、何かの拍子にいくつかが出力
されなくなったりします。ループの途中にbcastやbarrier等の同期があるので、
出力がないプロセスも計算そのものが停止しているということはないと思うのですが、
別のファイルや標準出力への出力も停止するのでうまく調べきれず、定かではありません。
かなり情報が少なくて申し訳ないのですが、考えうる原因、調査法、解決法もしくは
それに至らなくとも何か思いついたことでもあれば教えて頂けませんか?
0416デフォルトの名無しさん2010/02/08(月) 19:42:12
>>415
2桁のファイル名を決める整数が
違うプロセスで同じ整数になっちゃって・・・とか
とびとびになってしまって、とかは無いのかな?
PCとスパコンで違う並列数でやっておかしくなったのなら
同じ並列数(2とかw)でやってテストしてみては?

CPUが自分のプロセス番号(例題でよく変数名Myrankになるやつ)
を決める部分のチェックとかもやるといいかも。
とあるシステムでちゃんと動いてるので415さんのMPIの
(データ転送とかの)部分にミスがあるとは考えにくい、
という推定からすると他にはあまり思いつかないな。
0417デフォルトの名無しさん2010/02/09(火) 00:30:15
>>415
ノードローカルのディスクに書いてるとかいうオチならブチキレ
0418デフォルトの名無しさん2010/02/09(火) 02:35:40
でもたいていのシステムではジョブ終了時に一箇所にまとめるから
少なくともジョブ終了後にユーザーがファイルを移動する操作を
する必要は無いような気もするけど・・・・
その可能性は大いにあるね。
0419デフォルトの名無しさん2010/02/10(水) 18:08:04
問題のプロセスはファイル出力はせずに計算はちゃんと終了してるの?

mpi_finalizeを実行せずに終了してるのでは?
0420デフォルトの名無しさん2010/02/10(水) 20:33:47
MPI_Finalizeとファイル出力はなんも関係ない
0421デフォルトの名無しさん2010/02/11(木) 10:58:34
MPI_Finalizeとファイル出力はなんも関係ない
=> MPIとファイル出力はなんも関係ない
=> このスレとファイル出力はなんも関係ない
■ このスレッドは過去ログ倉庫に格納されています