< 目次

OpenMP* のクリティカル・セクション

OpenMP* のクリティカル・セクションを使用して、複数のスレッドがクリティカルなコード領域を同時に実行するのを防止し、1 つのアクティブなスレッドのみがコードで参照されているデータを更新します。クリティカル・セクションは、入れ子ではないミューテックスに適しています。

単一操作に対する細粒度の同期を提供する OpenMP* のアトミック操作とは異なり、クリティカル・セクションは複数操作に対する粗粒度の同期を提供します。

次を使用します。

オプションの(name)が省略されると、単一の名前なしグローバル・ミューテックスをロックします。共有ミューテックスによりパフォーマンスが大幅に低下しない場合、最も簡単なアプローチは名前なしの形式を使用することです。

ヒント

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

例えば、次のアノテーション付きの C/C++ シリアルプログラムについて考えてみます。

int count; 
void Tick() { 
     ANNOTATE_LOCK_ACQUIRE(0); 
          count++; 
     ANNOTATE_LOCK_RELEASE(0);
}..

次に、#include <omp.h> #pragma omp critical を追加した C/C++ 並列コード:

#include <omp.h> // .dll を検出できないロード時の問題を解決します 
int count; 
void Tick() { 
// ロック・アノテーションと入れ替えます
     #pragma omp critical 
          count++; 
}
..

次のようなアノテーション付きの Fortran シリアルコードについて考えてみます。

program ABC 
integer(kind=4) :: count = 0.contains 
subroutine Tick 
     call annotate_lock_acquire(0) 
          count = count + 1 
     call annotate_lock_release(0) 
end subroutine Tick.end program ABC

次に、use omp_lib!$omp critical および!$omp end criticalを追加した Fortran 並列コード:

program ABC 
use omp_lib 
integer(kind=4) :: count = 0...contains subroutine Tick 
     !$omp critical 
          count = count + 1 
     !$omp end critical 
end subroutine Tick 
.. 
..
end program ABC

関連情報