yohhoyの日記

技術的メモをしていきたい日記

OpenMPのC++言語統合提案

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 TBBMicrosoft PPLcombinable<T>クラス相当を提供すべきだろう。N3530中にも今後の提案で扱っていくとある。

関連URL

*1:機能的には paralleltask キーワード+taskwait で実現可能

*2:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3497.html