4

このコードを見てください。

シングルスレッド プログラム: http://pastebin.com/KAx4RmSJ . 以下でコンパイル:

g++ -lrt -O2 main.cpp -o nnlv2

openMP を使用したマルチスレッド: http://pastebin.com/fbe4gZSn でコンパイル:

g++ -lrt -fopenmp -O2 main_openmp.cpp -o nnlv2_openmp

デュアル コア システムでテストしました (したがって、2 つのスレッドが並行して実行されます)。ただし、マルチスレッド バージョンはシングル スレッド バージョンよりも低速です (また、不安定な時間が表示されます。数回実行してみてください)。どうしたの?どこで間違えたのですか?

いくつかのテスト:

シングルスレッド:

Layers Neurons Inputs --- Time (ns)

10 200 200 --- 1898983

10 500 500 --- 11009094

10 1000 1000 --- 48116913

マルチスレッド:

Layers Neurons Inputs --- Time (ns)

10 200 200 --- 2518262

10 500 500 --- 13861504

10 1000 1000 --- 53446849

何が悪いのかわかりません。

4

4 に答える 4

2

ここでの目標は、OpenMPを研究することですか、それともプログラムを高速化することですか?後者の場合、乗算加算コードを記述し、パスの数を減らし、SIMDを組み込む方が価値があります。

ステップ1:ループを組み合わせて、multiply-addを使用します。

// remove the variable 'temp' completely
for(int i=0;i<LAYERS;i++)
{
  for(int j=0;j<NEURONS;j++)
  {
    outputs[j] = 0;

    for(int k=0,l=0;l<INPUTS;l++,k++)
    {
      outputs[j] += inputs[l] * weights[i][k];
    }

    outputs[j] = sigmoid(outputs[j]);
  }

  std::swap(inputs, outputs);
}
于 2011-07-13T00:27:15.780 に答える
2

-static と -p でコンパイルし、実行してから gprof で gmon.out を解析すると、次のようになりました。

45.65% gomp_barrier_wait_end

これは、opemmp のバリア ルーチンではかなりの時間です。これは、他のスレッドが終了するまでの待機に費やされた時間です。並列 for ループを何度も (LAYERS) 実行しているため、並列 for ループが終了するたびに、他のすべてのスレッドが終了するまで戻らない暗黙のバリア呼び出しがあるため、並列で実行する利点が失われます。

于 2011-07-20T04:43:37.887 に答える
0

OpenMP を実際に使用した場所がわかりません - メイン ループの上で #pragma omp parallel を試してください... (たとえば、ここに文書化されています)

速度が遅いのは、OpenMP を含めて初期化したり、コードの肥大化を追加したり、それを有効にするために導入したコンパイラ フラグの結果としてコンパイルを変更したりすることが原因である可能性があります。あるいは、ループが非常に小さく単純であるため、スレッド化のオーバーヘッドがパフォーマンスの向上をはるかに超えています。

于 2011-07-13T01:41:40.837 に答える
0

何よりもまず、マルチスレッド構成でテストを実行し、procexp またはタスク マネージャーが 100% の CPU 使用率を表示することを確認してください。そうでない場合は、複数のスレッドも複数のプロセッサ コアも使用していません。

また、ウィキから取得:

環境変数

OpenMP アプリケーションの実行機能を変更する方法。ループ反復のスケジューリング、デフォルトのスレッド数などを制御するために使用されます。たとえば、OMP_NUM_THREADSは、アプリケーションのスレッド数を指定するために使用されます。

于 2011-07-12T23:57:28.333 に答える