3

単純な for ループを並列化する最初の OpenMP プログラムを作成しました。デュアル コア マシンでコードを実行したところ、1 スレッドから 2 スレッドに移行すると速度が向上しました。ただし、学校の Linux サーバーで同じコードを実行したところ、速度が向上しませんでした。さまざまなことを試した後、役に立たない printf ステートメントをいくつか削除すると、コードの速度が大幅に向上することに最終的に気付きました。以下は、私が並列化したコードの主要部分です。

#pragma omp parallel for private(i)
for(i = 2; i <= n; i++)
{
  printf("useless statement");
  prime[i-2] = is_prime(i);
}

printf の実装には、OpenMP が各スレッドで複製しなければならない大きなオーバーヘッドがあると思います。このオーバーヘッドの原因は何ですか? OpenMP がそれを克服できないのはなぜですか?

4

4 に答える 4

6

憶測ですが、おそらくstdoutはロックで守られていますか?

一般に、printfは他のリソース(ファイル、コンソールなど)と相互作用するため、コストのかかる操作です。

私の経験的な経験では、printfはWindowsコンソールでは非常に遅く、Linuxコンソールでは比較的高速ですが、ファイルまたは/ dev/nullにリダイレクトされた場合でも最速です。

printf-debuggingはアプリのパフォーマンスに深刻な影響を与える可能性があることがわかったので、慎重に使用しています。

ファイルまたは/dev/ nullにリダイレクトされたアプリケーションを実行して、これがかなりの影響を与えるかどうかを確認してください。これは、問題が発生する場所を絞り込むのに役立ちます。

もちろん、printfsが役に立たないのなら、なぜそれらはまったくループに入っているのでしょうか?

于 2010-04-26T06:30:07.203 に答える
3

@Willの答えを少し拡張するには...

stdout がロックによって保護されているかどうかはわかりませんが、stdout への書き込みがソフトウェア スタックのある時点でシリアル化されることは確かです。ステートメントが含まれていると、printfOP はおそらくループの並列化された実行ではなく、stdout への多くのシリアル書き込みの実行のタイミングを計っています。

OP がprintfステートメントを変更して include を追加することをお勧めしiます。何が起こるかを確認してください。

デュアル コア マシンでの明らかな速度向上については、統計的に有意でしたか?

于 2010-04-26T06:45:29.357 に答える
1

ここに並列 for ループがありますが、スケジューリングは指定されていません。

#pragma omp parallel for private(i)
for(i = 2; i <= n; i++)

OpenMP 3.0 標準で定義されているスケジューリング タイプがいくつかあります。OMP_SCHEDULE環境変数をtype[,chunk]where に設定することで変更できます

  • typeは、staticdynamicguided、またはautoのいずれかです
  • chunkは、チャンク サイズを指定するオプションの正の整数です

スケジュールの種類を変更する別の方法は、openmp 関数を呼び出すことですomp_set_schedule

is_prime関数はかなり高速です。/私は提案します/

  prime[i-2] = is_prime(i);

そのため、スケジューリングからのバリアの前に少数が実行される場合、問題は間違ったスケジューリング モードに起因する可能性があります。

内部にprintfは 2 つの部分があります /私は glibc を一般的な Linux libc 実装と考えています/

  1. フォーマット文字列を解析し、すべてのパラメータをバッファに入れます
  2. バッファーをファイル記述子に書き込みます (標準出力はデフォルトで glibc によってバッファーされるため、FILE バッファーに書き込みます)。

printf の最初の部分は並行して実行できますが、2 番目の部分はクリティカル セクションであり、 でロックされてい_IO_flockfileます。

于 2010-12-29T08:02:38.517 に答える
0

あなたのタイミングはどのくらいでしたか? printf のほうがずっと遅かったですか? 一部のタイトなループでは、printf が合計計算時間の大部分を占める場合があります。たとえば、is_prime() が非常に高速であるため、パフォーマンスは is_prime() の (並列化された) 呼び出しの数よりも printf の呼び出しの数によって決定されます。

于 2010-12-26T15:49:07.360 に答える