C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

GCC4.7.1: C++11 と OpenMP のちょっと惜しい関係

C++11から言語仕様のスレッディング周りが強化され、thread、atomic、mutexなどなど言語標準機能として扱える様になり、ちょっとやそっとやそれなりの用途でもintel TBBやBoost.Threadに頼らずにマルチスレッディングソフトウェアを開発し易くなりました。

なりました、が、ありがちなごく単純なforのちょっとやそっとの並行化如きであれば OpenMP で十分です。ところがC++11とOpenMPの組み合わせではちょっと惜しい部分があります。

OpenMP による for 並行化

とりあえず OpenMP による for の並行化ついて簡単に。

↑こんなソースを

g++ omp.cxx -fopenmp

とかビルドして実行すると、OpenMPにより0..9の出力が並行化されあばばばばばします。ちなみに-fopenmpを付けずにコンパイルすればプラグマは活きずにOpenMPによる並行化は行われず、0..9を順序良く出力します。

C++11 for

さて、C++11では区間全域(いわゆるforeachタイプの)に対するforとして range-based for なる構文が実装されました。

std::vector<unsigned> v(10);
std::iota(v.begin(), v.end(), 0);
for (auto a : v)
  cout << a;

こんなのですな。既に多くのC++erがこの構文に慣れて来た頃かもしれません。ところがこの構文は便利な OpenMP と組み合わせられません。

↑こんなソースを

g++ omp.cxx -fopenmp

とかビルドしようとすると、

omp.cxx: In function ‘int main()’:
omp.cxx:6:14: error: expected ‘=’ before ‘:’ token
omp.cxx:6:37: error: expected ‘;’ before ‘)’ token
omp.cxx:6:37: error: expected primary-expression before ‘)’ token
omp.cxx:9:1: error: expected primary-expression before ‘}’ token
omp.cxx:9:1: error: expected ‘)’ before ‘}’ token
omp.cxx:9:1: error: expected primary-expression before ‘}’ token
omp.cxx:9:1: error: expected ‘;’ before ‘}’ token
omp.cxx:6:3: error: invalid type for iteration variable ‘a’

とかなんとか激しく構文エラーを指摘されてしょんぼりする事になるでしょう(´・ω・`)

(´・ω・`)

今回は GCC 4.7.1 で試しました。

によればGCC 4.7系はOpenMP 3.1をサポートしているのだそうだけれど、

とか見てより新しい次のシリーズのOpenMP規格、OpenMP 4.0の仕様を見ても、C++C++98を基準にしたまま。 range-based forをOpenMPでちょちょいと並行化できる日は遠いのかも(´・ω・`)