C++1y(C++14)に向けた並列プログラミングモデルについてメモ。(PDF)N3530 Leveraging OpenMP infrastructure for language level parallelisationにて、OpenMP実装インフラをC++言語機能として統合する提案がなされている。初期提案のため骨子のみ。
OpenMPは主要な処理系にてサポート済みの機能であり、既にあるこの実装インフラを利用することで、新しい言語機能への対応が容易になる点を推している。従来の#pragma omp
を利用したOpenMP指示文の代替として、新しいC++キーワード/関数を幾つか導入する。
OpenMP | N3530 |
---|---|
parallel for指示文 | parallelforキーワード |
parallel task指示文 | paralleltaskキーワード |
taskwait指示文 | taskwait関数 |
parallel sections指示文 | (なし)*1 |
データ共有
データ共有属性を制御するshared/private節の代わりに、parallelfor構文の外から来る変数はshared/スコープ内で新たに宣言された変数はprivateとなる。ループカウンタはOpenMP同様に自動的にprivate扱い。
// C + OpenMP void func_c_omp(int n, int sv) { int i, pv; #pragma omp parallel for shared(sv) private(pv) for (i = 0; i < n; i++) { //... } } // N3530 void func_n3530(int n, int sv) { parallelfor (int i = 0; i < n; i++) { int pv; //... } }
リダクション演算
N3530では直接reduction節に相当する機能は示されていない。代わりに処理スレッド情報を返すmythreadid
, activethreads
関数とデータ配列を用いて、自前でリダクション処理を行う例が挙げられている。下記はN3530 Figure 6からの引用だが…非常にダサい。しかもC99のVLAを使っている?(一応C++1yへも提案*2されてはいる)
double compute(int length, double * values) { double total = 0.0; double totalarray[activethreads()]; // serial initialisation for (int i=0; i<activethreads(); i++) { totalarray[i] = 0.0; } parallelfor (int i=0; i<length; i++) // parallel computation { totalarray[mythreadid()] += values[i]; } for (int i=0; i<activethreads(); i++) // serial finalisation { total += totalarray[i]; } return total; }
メモ:リダクション演算に関しては、少なくともIntel TBBやMicrosoft PPLのcombinable<T>
クラス相当を提供すべきだろう。N3530中にも今後の提案で扱っていくとある。
関連URL
*1:機能的には paralleltask キーワード+taskwait で実現可能
*2:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3497.html