Home > Archives > 2007年10月

2007年10月

gcc の OpenMP で遊ぶ

とりあえずやってみることその一.演算子のオーバロードがダメと言われても試したくなるのが人間.

struct DOUBLE {
    double x;
    double y;
    DOUBLE() : x(0), y(0) { }
    DOUBLE(int d) {
        x = d;
        y = d;
    }
    DOUBLE operator+(const DOUBLE& a) const {
        DOUBLE z;
        z.x = x + a.x;
        z.y = y + a.y;
        return z;
    }
};
DOUBLE a1(int n, DOUBLE *a)
{
    int i;
    DOUBLE r = 0;
#pragma omp parallel for reduction(+:r)
    for(i = 0; i < n; i++) {
        r = r + a[i];
    }
    return r;
}

コンパイルしたら

 error: 'r' has invalid type for 'reduction' 

と文句を言われた.だめらしい.

次,中途半端にオーバーロードしてみる.

struct DOUBLE {
        double x;
        double y;
        DOUBLE() : x(0), y(0) { }
        DOUBLE(int d) {
                x = d;
                y = d;
        }
};
 
double operator+(double a, DOUBLE b) 
{
    return b.x - a;
}
 
double a1(int n, DOUBLE *a)
{
    int i;
    double r = 0;
#pragma omp parallel for reduction(+:r)
    for(i = 0; i < n; i++) {
        r = r + a[i];
    }
    return r;
}

コンパイルしても文句言われない.でも演算子の結合性がないので当然ながら結果はおかしい.各スレッドでの結果をマージする部分では通常の + になってしまうので当り前だけど.

ついでに,次の無意味なオーバーロードは正しい計算がされる.

double operator+(double a, DOUBLE b) 
{
    return a - b.x;
}

結局,全要素に - を map して + で reducction するだけだから.

結論:reduction に演算子オーバーロードはやっぱり使えなかった.でもこうなると行列を for 文で掛けまくるとかいう操作は並列化してくれないのかぁ.行列積自体は結合的だけど展開した式での各要素は reduction の式にならないし.使えん.

SRM 373 DIV 1

体力が尽きているので一番簡単な問題だけ解いて寝なおした.

250点問題:フォントを小さい方から試せばいいだけなのですぐ終わる.

500点問題:チェックしなければならない時刻は,任意の歩行者の組の間隔が車幅になるときと歩行者と横断歩道の開始点との差が車幅になるときなので,これらをチェックするだけ.でも書くのが面倒なので寝た.

1000点問題:螺旋かどうかの判定に線分の交差判定とか考えないといけないから… パス.まあ,判定ができたとしても総当たりでいいのかどうかよくわからん.

SRM 372 DIV 1

問題との相性がよかったので珍しく部屋内で二番目だったらしい.

250点問題:罰金って fine なんだなぁ,知らんかった.普通にシミュレーションすれば終わり.でも罰金の計算間違って時間をとられる.

500点問題:DPでいけるらしいのだけど状態空間の取り方が今一つ理解できてない.金と桁と余りのようなものとでできるらしいのだけど…ちょっと考えてよくわからなかったからパス.

1000点問題:二部グラフのマッチングで最大重みと最小重みを求めて終わり.なんとなく500点問題より簡単な気が… とりあえず最少費用流のアルゴリズムを書くのに時間喰って点数半分くらい.

gcc4.2 で OpenMP 使ってみた

今更ながらだけど gcc4.2 で OpenMP 使えるのを試してみた.使うにはふつうに OpenMP のディレクティブ書いて -fopenmp つけてコンパイルするだけ.あとは OMP_NUM_THREADS 環境変数にスレッド数をぶち込んで動かす.

で,parallel for とか reduction(+:r) とかで並列実行されるのを確認.ただ,reduction で本来の計算以外に結構時間取られてるっぽいので要調査かな.

あと,OpenMP 2.5 の仕様をみると reduction のオペレータはオーバーロード禁止かついわゆる C or C++ の演算子しか使えないとあるのでgccでもそうなのか試してみよう.オーバーロードくらい許してくれないと何にも出来ん.

SRM 371 DIV 1

直前まで寝ててそのまま寝ぼけてた気がする…

250点:何なんだこの国内予選A問題は?

500点:ソートしてから弾性マッチング.なのにおもむろに一般的な二部グラフの重みつきマッチングをやり始め… 途中で実装間違えて時間オーバー.

100点:時間なし.がんばって数えればいいのかな?

SRM 369 DIV 1

チャレンジのみの150点.でもシステム側の都合で rating は変化しない.

250点:よく考えたらいくらでも細切れにできるんだなぁ.ということで,少ない方はいつでも count まで使いきれる.多い方は,max まで連続したチャンクの集まりの上限を少ない方の count + 1 個まで作れる.ということで,この最大個数以下かつ count までが多い方の使える数なわけで… と,ちゃんと考えるのが面倒で投げ出した.

500点:単純にやると指数時間(入力の数字の大きさに関して線形)かかるので却下.大小関係が保持される間は3周期のパタンを繰り返すことを使わないとだめ.基本的にはユークリッドの互助法みたいな進み方するので入力ビット数の線形ですむはず.でも時間なかった…

1000点:面倒そうなのでパス.正しいプログラムを見てみたいものだ.

SRM 368 DIV 1

変に時間を食って一問しか解けんかった・・・

250点問題:ベルマンフォード書いて終わり.だが,いくつか書き間違えてデバッグに時間を喰う.

500点問題:線分の交差判定のルーチンを書いて,あとは union/find で終わり.のはずだけど,判定式を書き切れなかったのでアウト.

1000点問題:アルファベットのバイナリエンコードに曖昧性があるかの判定だけど… 3つ以上のデコード列を持つ最小の文字列を探さないとならないらしい.愚直に全生成とかだとだめだよなぁ.よくわからず.

Home > Archives > 2007年10月

Search
Feeds

Page Top