5

巨大なファイル (3x280 GB) を読み取り、ファイル内のデータにフィッティング手順を実行するプログラムを作成しています。このようなプログラムを並列化することは非常に便利で、OpenMP で簡単に実行できます。

私が理解していないのは、OpenMP でプライベート変数がどのように取得されるかです。誰もが知っているように、fstream のオブジェクトはコピー不可であり、直観的に、私はそれをプライベート オブジェクトとして使用できませんでした。したがって、ファイルのリーダーは共有されました。

後で問題が発生したので、fstreams を非公開にしてみようと思いました...そして何だと思いますか? 出来た!!!これはどのように可能でしょうか?! オブジェクトがコピー不可能な場合、OpenMP はカーネルごとに同じオブジェクトの異なるコピーをどのように使用できますか?

これは私のプログラムがどのように見えるかです:

fstream dataReaderX(Dirs[0].c_str(), ios::in | ios::binary);
fstream dataReaderY(Dirs[1].c_str(), ios::in | ios::binary);
fstream dataReaderZ(Dirs[2].c_str(), ios::in | ios::binary);
#pragma omp parallel num_threads(cpus_num) shared(...) private(...,dataReaderX,dataReaderY,dataReaderZ)
{
...
}

ありがとうございました。

4

1 に答える 1

7

firstprivate変数はコピーされますがprivate、後者の場合はデフォルトのコンストラクターが呼び出されます。

セクション 2.9.3.3 -private句:

新しいリスト項目は、初期化子なしでローカルに宣言されたかのように、初期化されるか、未定義の初期値を持ちます。クラス型のさまざまなプライベート変数のデフォルト コンストラクターが呼び出される順序は規定されていません。クラス型のさまざまなプライベート変数の C/C++ デストラクタが呼び出される順序は規定されていません。

簡単なデモンストレーション コードを次に示します。

#include <fstream>
#include <stdio.h>
#include <omp.h>

int main (void)
{
   std::fstream reader("test.txt", std::ios::in);
   printf("Main thread: reader.is_open() = %d\n", reader.is_open());
   #pragma omp parallel private(reader)
   {
      printf("Thread %d: reader.is_open() = %d\n",
             omp_get_thread_num(), reader.is_open());
   }
   return 0;
}

そして、期待どおりの出力は次のとおりです。

Main thread: reader.is_open() = 1
Thread 1: reader.is_open() = 0
Thread 0: reader.is_open() = 0
Thread 3: reader.is_open() = 0
Thread 2: reader.is_open() = 0

面白いことに、インテル® C++ コンパイラーが内部エラー (アサーションの失敗) でエラーになることがあります。バージョン 11.1、12.0、および 12.1 でテスト済みです。一方、GNU C++ コンパイラは標準に準拠しています (上記の出力は からのものですg++)。代わりに を使用すると、両方のコンパイラーが文句を言いfirstprivateますが、インテル C++ コンパイラーは再び内部エラーでエラーになります。

ばかげているように聞こえるかもしれませんが、使用している特定のコンパイラで OpenMP サポートが有効になっていることを確認しましたか?

于 2012-06-12T18:25:34.933 に答える