パラレルノート#4-OpenMPデザインの調査を継続

画像

OpenMPテクノロジーの知識を継続し、いくつかの機能と新しいディレクティブを検討しましょう。



OpenMPには多くのヘルパー関数があります。 これらを使用するには、ヘッダーファイル<omp.h>を含めることを忘れないでください。



ランタイム関数


これらの関数を使用すると、OpenMP環境のさまざまなパラメーターを照会および設定できます。



関数名がomp_set_で始まる場合、並列領域の外部でのみ呼び出すことができます。 他のすべての関数は、並列領域内と並列領域外の両方で使用できます。



同期/ロック機能


OpenMPでは、特定のタイプの同期を許可するディレクティブがあるため、これらの関数を使用せずに並列コードを構築できます。 ただし、場合によっては、これらの機能は便利であり、必要なこともあります。



OpenMPには、シンプルとネストの2種類のロックがあります。 添付ファイルの接尾辞は「nest」です。 ロックは、未初期化、ロック、ロック解除の3つの状態のいずれかになります。



同じスレッドであっても、単純ロック(omp_lock_t)を複数回設定することはできません。 ネストされたロック(omp_nest_lock_t)は単純なものと同じです。ただし、スレッドが既にそれに属するネストされたロックを設定しようとすると、ブロックされません。



次に、説明した機能を使用するコードの例を示します。 順番に作成されるすべてのスレッドには、「作業開始」および「作業終了」メッセージが表示されます。 1つのスレッドからのこれら2つのメッセージの間に、閉じたセクションへの入力に失敗したときに表示される他のスレッドからのメッセージが存在する場合があります。



  omp_lock_tロック;
 int n;
 omp_init_lock(&ロック);
 #pragma omp parallel private(n)
 {
   n = omp_get_thread_num();
   while(!omp_test_lock(&lock))
   {
     printf( "Wait ...、thread%d \ n"、n);
    睡眠(3);
   }
   printf( "作業開始、スレッド%d \ n"、n);
  睡眠(5);  //作業...
   printf( "作業終了、スレッド%d \ n"、n);
   omp_unset_lock(&ロック);
 }
 omp_destroy_lock(&ロック); 




4つのコアを持つマシンでは、次の出力を取得できます。



作業を開始、スレッド0

待って...、スレッド1

待って...、スレッド2

待って...、スレッド3

待って...、スレッド2

待って...、スレッド3

待って...、スレッド1

作業終了、スレッド0

作業を開始、スレッド2

待って...、スレッド3

待って...、スレッド1

待って...、スレッド3

待って...、スレッド1

作業終了、スレッド2

作業を開始、スレッド3

待って...、スレッド1

待って...、スレッド1

作業終了、スレッド3

作業を開始、スレッド1

作業終了、スレッド1



タイマー機能




これについては、関数の紹介を終了し、いくつかの新しいディレクティブを検討します。 これらのディレクティブは、並列領域を作成するためのオプションと呼ばれます。



if(条件)


条件による並列領域の実行。 複数のスレッドの作成は、特定の条件が満たされた場合にのみ実行されます。 条件が満たされない場合、コードはシーケンシャルモードで実行されます。



使用例:

  voidテスト(bool x)
 {
   #pragma omp parallel if(x)
   if(omp_in_parallel())
   {
     #pragma omp single
     printf_s( "%dスレッドで並列化\ n"、
              omp_get_num_threads());
   }
  他に
   {
     printf_s( "シングルスレッド\ n");
   }
 }

 int _tmain(int argc、_TCHAR * argv [])
 {
  テスト(false);
  テスト(true);
   0を返します。
 } 




仕事の結果:

 シングルスレッド
 4つのスレッドで並列化 




num_threads


並列領域を実行するスレッドの数の明示的な設定。 デフォルトでは、omp_set_num_threads()関数を使用して設定された最後の値が選択されます。



上記の例を次のように変更した場合:



  ...
 #pragma omp parallel if(x)num_threads(3)
 ... 




次の出力が得られます。



 シングルスレッド
 3つのスレッドで並列化 




Parallel Notesの次号では、続きます...



All Articles