2

実行時間の長いシミュレーション プログラムがあり、高速化のために一部のコードを並列化するために OpenMP を使用する予定です。私は OpenMP を初めて使用し、次の質問があります。

シミュレーションが確率的なものであることを考えると、次のデータ構造があり、シードされたエージェントの年齢別の数をキャプチャする必要があります [編集済み: 一部のコードが編集されました]:

class CAgent {
    int ageGroup;
    bool isSeed;
    /* some other stuff */
};

class Simulator {
    std::vector<int> seed_by_age;
    std::vector<CAgent> agents;
    void initEnv();
    /* some other stuff */
};

void Simulator::initEnv() {
     std::fill(seed_by_age.begin(), seed_by_age.end(), 0);

     #pragma omp parallel
     {
          #pragma omp for
          for (size_t i = 0; i < agents.size(); i++)
          {
               agents[i].setup(); // (a)
               if (someRandomCondition())
               {
                   agents[i].isSeed = true;
                   /* (b) */
                   seed_by_age[0]++; // index = 0 -> overall
                   seed_by_age[ agents[i].ageGroup - 1 ]++;
               }
          }
     } // end #parallel
} // end Simulator::initEnv()

変数seed_by_ageはスレッド間で共有されるため、適切に保護する必要があることはわかっています。したがって、(b) では、使用#pragma omp flush(seed_by_age[agents[i].ageGroup])しましたが、コンパイラは「エラー: '[' トークンの前に ')' が必要です」と不平を言います

私は削減を行っていません。可能であれば、「クリティカル」ディレクティブを避けようとしています。それで、私はここで何か不足していますか?ベクターの特定の要素を適切に保護するにはどうすればよいですか?

多くの感謝と私はどんな提案にも感謝します.

  • 開発ボックス: 2 コア CPU、ターゲット プラットフォーム 4-6 コア
  • プラットフォーム: Windows 7、64 ビット
  • MinGW 4.7.2 64 ビット (rubenvb ビルド)
4

3 に答える 3

1
#pragma omp flush(seed_by_age[agents[i]].ageGroup)

ブラケットをすべて閉じてみると、コンパイラ エラーが修正されます。

于 2013-06-28T07:14:59.693 に答える
0

残念ながら、#pragma omp flush ステートメントは、データを保護し、ここで競合状態を防ぐには不十分です。someRandomCondition() が非常に限られた数のケースでのみ true の場合、速度をあまり落とさずに、ベクトルの更新にクリティカル セクションを使用できます。あるいは、ベクトル seed_by_age のサイズが大きすぎない場合 (私が推測する)、並列ブロックを離れる直前にマージするスレッドごとにベクトルのプライベート バージョンを用意すると効率的です。

于 2013-06-28T09:29:28.800 に答える