多少の余計な計算を必要とするが,数回分の通信をまとめてやってしまう.今回のプログラムは値の更新に左の値しか使わないので楽.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; } } }
- Newer: AWK - はじめ