< 目次

データの並列処理 - OpenMP* ループ (複雑な反復制御)

場合によっては、ループが複雑な制御フローを持つことがあります。このような状況で OpenMP* を使用する場合、単純なループを扱う場合よりも多くのことが求められます。タスク本体では、アノテーション・サイト内で定義されている自動変数にアクセスしてはなりません。このような変数は、タスクの実行前または実行中に破棄される可能性があります。また、task 構造で参照される変数はデフォルトで firstprivate であることに注意してください。

C/C++ コードについて考えてみます。

extern char a[];
int previousEnd = -1;
 ANNOTATE_SITE_BEGIN(sitename);
   for (int i=0; i<=100; i++) {
      if (!a[i] || i==100) {
         ANNOTATE_TASK_BEGIN(do_something);
             DoSomething(previousEnd+1,i);
         ANNOTATE_TASK_END();
         previousEnd=i;
      }
   }
ANNOTATE_SITE_END();

ここでは、OpenMP* の task プラグマを使用します。そうでないと、このようなループの並列化はかなり困難になります。ループを並列化する 1 つの手法として、DoSomething() 呼び出しを単純にスポーンする方法があります。

 
extern char a[]; 
int previousEnd = -1;
#pragma omp parallel
 {
#pragma omp single
  {
... 
   for (int i=0; i<=100; i++) {
   
     if (!a[i] || i==100) 
     {
     #pragma omp task 
          DoSomething(previousEnd+1,i);
     }
   }
 }
}

ここで、DoSomething への引数は参照渡しではなく、値渡しであることが重要です。それは、previousEndi が、スポーンされたタスクの実行前または実行中に変更される可能性があるためです。

次の Fortran コードついて考えてみます。

...
logical(1) a(200)
integer(4) i, previousEnd
...
previousEnd=0
call annotate_site_begin(functions)
do i=1,101
  if a(.not. a(i)) .or.(i .eq.101) then
  call annotate_task_begin(do_something)
    call DoSomething(previousEnd+1, i)
  call annotate_task_end
  endif
end do
call annotate_site_end

ここでは OpenMP* の task ディレクティブを使用します。そうでないと、このようなループの並列化はかなり困難となるでしょう。上記のループを並列化する 1 つの手法として、DoSomething() 呼び出しを単純にスポーンする方法があります。

 
...
logical(1) a(200)
integer(4) i, previousEnd
...
previousEnd=0
!$omp parallel
!$omp single
do i=1,101
  if a(.not. a(i)) .or.(i .eq.101) then
  !$omp task
     call DoSomething(previousEnd+1, i)
  !$omp end task
  endif
end do
!$omp end parallel
   

parallel ディレクティブで囲まれた静的範囲内では、omp task プラグマやディレクティブを記述する必要はありません。

ヒント

OpenMP* 並列フレームワークを使用してコードを書き直した後、インテル® Advisor でパフォーマンスを解析できます。Vectorization and Code Insights (ベクトル化とコードの調査) パースペクティブを使用して、OpenMP* コードがどの程度ベクトル化されているか解析するか、Offload Modeling (オフロードのモデル化) パースペクティブで GPU でのパフォーマンスをモデル化できます。

関連情報