Home > プログラミング > gcc の OpenMP で遊ぶ

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 の式にならないし.使えん.

★下記に2つの英単語をスペースで区切って入力してください

Home > プログラミング > gcc の OpenMP で遊ぶ

Search
Feeds

Page Top