11

さまざまな状況でコードを実行した結果、奇妙な動作と思われる結果が生じました。私のテストは、HT を搭載したデュアル コア Intel Xeon プロセッサで行われました。

OpenMP '#pragma' ステートメントなし、合計実行時間 = 507 秒

OpenMP の「#pragma」ステートメントで 1 コアを指定すると、合計実行時間 = 117 秒

OpenMP の「#pragma」ステートメントで 2 コアを指定すると、合計実行時間 = 150 秒

OpenMP の「#pragma」ステートメントで 3 コアを指定すると、合計実行時間 = 157 秒

OpenMP の「#pragma」ステートメントで 4 コアを指定すると、合計実行時間 = 144 秒

私のopenmp行をコメントアウトすると、openmpを使用しない1つのスレッドとopenmpを使用する1つのスレッドの間でプログラムの速度が大幅に低下する理由がわかりません。

私が変更しているのは次のとおりです。

//#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1) schedule(guided)

and...

#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1,2,3,4) schedule(guided)

とにかく、なぜこれが起こっているのか、誰かが知っているなら、私に知らせてください!

助けてくれてありがとう、

ブレット

編集:ここでいくつかのコメントに対処します

num_threads(1)、num_threads(2) などを使用しています。

さらに調査すると、コードに「スケジュール (ガイド付き)」行が含まれているかどうかに基づいて、結果に一貫性がないことがわかりました。

-スケジュール (ガイド付き) ラインを使用している場合、スレッドの数に関係なく、最速のソリューションを生成します。- デフォルトのスケジューラーを使用している場合、結果が大幅に遅くなり、値が異なります - スケジュール (ガイド付き) を使用すると、スレッドを増やしても改善が得られません - スケジュール (ガイド付き) を使用しない場合、スレッドを追加すると改善が得られます

スケジュール(ガイド付き)が何をするのかについての十分な説明が見つからなかったと思いますが、最も時間のかかる反復が最初に発生するようにループを分割しようとすることを理解しています。 1 つのスレッドが他のスレッドが反復を完了するまで待機する時間。

私の ~ 900 反復ループでは、スケジュール (ガイド付き) を使用すると、~ 200 回の反復のみを処理しているように見えますが、スケジュール (ガイド付き) を使用しない場合は、900 回すべての反復を処理しています。何かご意見は?

4

1 に答える 1

8

OpenMP には、かなりの同期オーバーヘッドがあります。多くの作業を行う非常に大きなループがあり、ループ内同期が ない場合を除き、一般的に OpenMP を使用する価値がないことがわかりました。

スレッド数を 1 に設定すると、OpenMP はループを実装する OpenMP プロシージャに対してプロシージャ コールを実行するだけなので、オーバーヘッドは最小限に抑えられ、パフォーマンスは非 OpenMP の場合と本質的に同じになると思います。

それ以外の場合、OpenMP はいくつかのセマフォを設定し、「ワーカー」スレッドがウェイクアップするのを待って、データ構造へのアクセスを同期し、設定するループ パラメーターを伝えてから、作業を行うルーチンを呼び出します。動作すると、マスタースレッドに再度シグナルを送ります。この同期は、スレッドが実行する作業のチャンクごとに発生する必要があり、同期のコストは自明ではありません。

STATIC スケジューリング オプションを使用すると、特にコア数に比べてループの反復回数が多い場合に、スケジューリング/同期のオーバーヘッドを削減するのに役立ちます。

于 2011-03-14T13:13:05.170 に答える