2011-11-15 10 views
2

サードパーティによって書かれた大きなプログラムを並列化しようとしています。コードを公開することはできませんが、私がやりたいことの最も近い例を試してみます。 以下のコードに基づいています。ご覧のように、 "parallel"という節はwhileループの中にあるので、スレッドの作成/破壊はそれぞれの反復で行われますが、これはコストがかかります。 私はInitializors ...などを "while"ループの外に移動することはできません。プログラムを実行するたびにスレッドを作成するようにOpenMPに要求するにはどうすればよいですか?

--Baseコード

void funcPiece0() 
{ 
    // many lines and branches of code 
} 


void funcPiece1() 
{ 
    // also many lines and branches of code 
} 

void funcCore() 
{ 
    funcInitThis(); 
    funcInitThat(); 

#pragma omp parallel 
    { 
#pragma omp sections 
     { 
#pragma omp section 
      { 
       funcPiece0(); 
      }//omp section 
#pragma omp section 
      { 
       funcPiece1(); 
      }//omp section 
     }//omp sections 
    }//omp parallel 

} 

int main() 
{ 

    funcInitThis(); 
    funcInitThat(); 
#pragma omp parallel 
    { 
    while(1) 
    { 
     funcCore(); 
    } 
    } 

} 

私は何をしようとすると、単位の反復作成/破壊を回避し、プログラムの開始/終了時に一度、それを作ることです。私は "平行"句の移動に多くのバリエーションを試しました。私は基本的に同じエッセンスを持っています:(1つのスレッド作成/破壊プログラムごとの実行) - 私は試してみましたが、初期化関数で "不正なアクセス"に失敗しました。

void funcPiece0() 
{ 
    // many lines and branches of code 
} 


void funcPiece1() 
{ 
    // also many lines and branches of code 
} 

void funcCore() 
{ 
    funcInitThis(); 
    funcInitThat(); 

//#pragma omp parallel 
// { 
#pragma omp sections 
     { 
#pragma omp section 
      { 
       funcPiece0(); 
      }//omp section 
#pragma omp section 
      { 
       funcPiece1(); 
      }//omp section 
     }//omp sections 
// }//omp parallel 

} 

int main() 
{ 

    funcInitThis(); 
    funcInitThat(); 

    while(1) 
    { 
     funcCore(); 
    } 

} 

-

すべてのヘルプは非常にいただければ幸いです! ありがとう!

+0

OpenMPのWebサイトには、OpenMPに関する質問を投稿できるフォーラムがあります。http://openmp.org/forum/ –

答えて

2

OpenMPは、開始時にワーカースレッドのみを作成します。並列プラグマはスレッドを生成しません。どのようにしてスレッドが生成されたと判断するのですか?

+0

にお返事ありがとうございます。私のプログラムはハングし、コンパイラを使ってデバッガで一時停止すると、 "pragma omp parallel"という関数を実行しているワーカースレッドが多く見えました。スレッドは「スポーンされています」とはどこにありますか? – user598208

+1

スレッドは、プログラムの起動時に(または実装によっては最初に必要なときに)開始されます。他の場所でプログラムを一時停止すると、スレッドがまだそこにあることがわかります – crazyjul

0

これを行うことができます!ここで重要な点は、ループを1つの並列セクション内に移動し、繰り返しを行うかどうかを決定するために使用されるものがすべて同じスレッドであることを確認することです。私は共有変数を使用し、ループ条件がチェックされる直前に同期を行いました。

ので、このコード:最も重要なことは、すべてのスレッドがで同じポイントで同じ決定を下すことを確認している

#pragma omp parallel 
{ 
    #pragma omp single 
    { 
    initialize(); //if initialization cannot be parallelized 
    } 
    while (some_condition_using_shared_variable) { 
    some_parallel_work(); 
    update_some_condition_using_shared_variable(); 
    #pragma omp flush 
    } 
} 

initialize(); 
while (some_condition) { 
    #pragma omp parallel 
    { 
    some_parallel_work(); 
    } 
} 

はこのようなものに変換することができますあなたのコード。

最終的な考えとして、本質的にはスレッドの作成/破棄(スレッドが#pragma omp並列が開始/終了するたびにスレッドの意思決定のための同期オーバーヘッドになる)のオーバーヘッドをトレードすることです。私は同期が速くなければならないと考えていますが、これは常にそうでないかもしれないいくつかの多くのパラメータがあります。

関連する問題