2006年10月18日
通信を複数まとめてみる
多少の余計な計算を必要とするが,数回分の通信をまとめてやってしまう.今回のプログラムは値の更新に左の値しか使わないので楽.CPUの力がある場合は2倍から3倍くらい速くなった(16回位まとめて).次はキャッシュでも考えて…
ループ始めに毎回通信:
MPI_Request reqs1, reqr1;
for(int t = 0; t < T; t++){
if(!ISLAST())
MPI_Isend(U + Len, 1, MPI_DOUBLE, Rank + 1, TAG1, MPI_COMM_WORLD, &reqs1);
if(!ISROOT())
MPI_Irecv(U , 1, MPI_DOUBLE, Rank - 1, TAG1, MPI_COMM_WORLD, &reqr1);
else
U[0] = 1;
if(!ISLAST())
MPI_Wait(&reqs1, MPI_STATUS_IGNORE);
if(!ISROOT())
MPI_Wait(&reqr1, MPI_STATUS_IGNORE);
register double *u = U;
register double pu = *u++;
for(double const *e = u+Len; u != e; u++){
register double cu = *u;
*u = (1 - MU) * cu + MU * pu;
pu = cu;
}
}
ループ始めに R 回分通信しとく:
MPI_Request reqs1, reqr1;
for(int t = 0; t < T; t+=R){
if(!ISLAST())
MPI_Isend(U + Len, R, MPI_DOUBLE, Rank + 1, TAG1, MPI_COMM_WORLD, &reqs1);
if(!ISROOT())
MPI_Irecv(U , R, MPI_DOUBLE, Rank - 1, TAG1, MPI_COMM_WORLD, &reqr1);
else
U[R-1] = 1;
if(!ISLAST())
MPI_Wait(&reqs1, MPI_STATUS_IGNORE);
if(!ISROOT())
MPI_Wait(&reqr1, MPI_STATUS_IGNORE);
for(int p = 0; p < R; p++) {
int q = (ISROOT()) ? R-1 : p;
double *u = U+q;
register double pu = *u++;
for(double const *e = u+Len+R-q-1; u != e; u++){
register const double cu = *u;
*u = (1 - MU) * cu + MU * pu;
pu = cu;
}
}
}
- Comments: 0
- TrackBack (Close): -