とりあえずやってみることその一.演算子のオーバロードがダメと言われても試したくなるのが人間.
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 の式にならないし.使えん.
- Newer: AWK - はじめ