3

次の恥ずかしい並列ループがあります

//#pragma omp parallel for
for(i=0; i<tot; i++)
    pointer[i] = val;

#pragma 行のコメントを外すとパフォーマンスが低下するのはなぜですか? openmp を使用してこの for ループを並列化すると、プログラムの実行時間がわずかに増加します。各アクセスは独立しているので、プログラムの速度が大幅に向上するはずではありませんか?

この for ループが tot の大きな値に対して実行されない場合、オーバーヘッドによって速度が低下する可能性はありますか?

4

1 に答える 1

5

共有メモリ環境で複数のスレッドを使用してパフォーマンスを達成するには、通常、次の要素に依存します。

  1. タスクの粒度
  2. 並列タスク間の負荷分散。
  3. 並列タスク数/使用コア数;
  4. 並列タスク間の同期の量。
  5. アルゴリズムの境界のタイプ。
  6. 機械のアーキテクチャ

上記の各ポイントについて、簡単に概要を説明します。

  1. 並列タスクの粒度が、並列化のオーバーヘッド(スレッドの作成や同期など)を克服するのに十分かどうかを確認する必要があります。おそらくループの反復回数であり、計算pointer[i] = val;ではスレッド作成のオーバーヘッドを正当化するのに十分ではありません。ただし、タスクの粒度が大きすぎると、負荷の不均衡などの問題が発生する可能性があることに注意してください。

  2. ロード バランス (スレッドあたりの作業量) をテストする必要があります。理想的には、各スレッドが同じ量の作業を計算する必要があります。あなたのコード例では、これは問題ではありません。

  3. ハイパースレッディングを使用していますか?! コアよりも多くのスレッドを使用していますか?! もしそうなら、スレッドはリソースを求めて「競合」を開始し、これがパフォーマンスの低下につながる可能性があるためです。

  4. 通常、スレッド間の同期の量を減らす必要があります。その結果、それを達成するために、より細かい同期メカニズムやデータの冗長性 (他のアプローチの中でも) を使用することがあります。あなたのコードにはこの問題はありません。

  5. コードの並列化を試みる前に、それがメモリや CPU などに依存しているかどうかを分析する必要があります。メモリが制限されている場合は、並列化に取り組む前に、キャッシュの使用を改善することから始めることができます。このタスクでは、プロファイラーの使用を強くお勧めします。

  6. 基盤となるアーキテクチャを最大限に活用するには、マルチスレッド アプローチでそのアーキテクチャの制約に取り組む必要があります。たとえば、アーキテクチャで実行するための効率的なマルチスレッド アプローチをSMP実装することは、アーキテクチャで実行するためにそれを実装することとは異なりNUMAます。後者の場合、メモリ アフィニティを考慮する必要があります。

編集: @Hristo lliev からの提案

  1. スレッド アフィニティ: 「スレッドをコアにバインドすると、データの局所性が向上するため、一般的にパフォーマンスが向上し、NUMA システムではさらに向上します。」

ところで、マルチスレッド アプリケーションを開発するためのインテル ガイドを読むことをお勧めします。

于 2012-11-25T19:25:23.867 に答える