No Such Blog or Diary

«Prev || 1 | 2 | 3 |...| 1231 | 1232 | 1233 |...| 1349 | 1350 | 1351 || Next»

通信を複数まとめてみる

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

さて…

遅そうなプログラムの最適化でもしようかねぇ.とりあえずシーケンシャル部分から書き換え.無駄に配列使わず上書きで行く.次は通信をまとめてみようか?

配列2本を使う:

        for(int i = 1; i <= Len; i++)
            V[i] = (1 - MU) * U[i] + MU * U[i - 1];      
        double *tmp = U; U = V; V = tmp;

こんなものは一本で十分:

        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;
        }            
 

これで一回のスッテプでのメモリアクセスが一箇所になった.良し.

どこからともなく梅酒

nihonshude.JPG

新宿のタカシマヤにて購入,たぶん1000円.岡山の日本酒で漬けた梅酒.やっぱりおいしい.アルコール度数が6度程度と低いのでいくらでも飲める.梅乃宿のと比べると度数が低いということもあるけど良い感じのさっぱり感があるかなと.次は同じところの白桃酒でも試してみようか?

ジャージャー麺

テンメンジャンがまだあったのでジャージャー麺を大量生成.4人前を2食に分けて喰う.ボケてテンメンジャン入れていためる前にスープを突っ込み味が… まあ,気にせず喰えたのでよしとしよう.

GLAN TANK に bind 入れる

久々にLAN内にDNSをおいてみる.あんまり意味無いけどURLの長さが縮まったのでよしとしよう.次はルータにやらせてる DHCP を移行しようか?

桁数に線形なループ回数の足し算 in sed

インクリメントだと桁数に指数的になってしまうので筆算のように計算するスクリプトを書いてみた.メイン部分はキャリーと足される二つの数の全パターンについて次のキャリーと一桁の答えを生成する正規表現マッチ連発部分.普通にやると全部で200通りになってしまうので少々まとめて40通りに抑えたが… 手で書くのは面倒なのでプログラムに機械生成させて手を抜く.もっとスマートなプログラムが出来ないかなぁ?

sum.sedgen.java

«Prev || 1 | 2 | 3 |...| 1231 | 1232 | 1233 |...| 1349 | 1350 | 1351 || Next»
Search
Feeds

Page Top