flush ディレクティブは、明示的または暗黙的にかかわらず、実装側で、チーム内のすべてのスレッドがメモリ内で特定のオブジェクト (以下で指定) に対する一貫したビューを持つことが必要な "スレッド間の" シーケンス ポイントを指定します。 これは、このオブジェクトを参照する前の式の評価が完了し、後続の評価がまだ開始されていないポイントになります。 たとえば、コンパイラがレジスタからメモリにオブジェクトの値を復元しなければならない場合や、ハードウェアが、メモリへの書き込みバッファーをフラッシュし、メモリからオブジェクトの値を再読み込みする必要がある場合などです。
flush ディレクティブの構文は次のとおりです。
#pragma omp flush [(variable-list)] new-line
同期を必要とするオブジェクトは、すべて変数で指定できます。これらの変数はオプションの variable-list で指定できます。 variable-list にポインターを指定すると、そのポインターが指すオブジェクトではなく、ポインターそのものがフラッシュされます。
variable-list を持たない flush ディレクティブでは、自動ストレージ存続期間中のアクセスできないオブジェクトを除いてすべての共有オブジェクトが対象となります。 この場合、通常、variable-list を持つ flush よりオーバーヘッドが増大します。次のディレクティブに対しては、variable-list を持たない flush ディレクティブが暗黙的に指定されます。
barrier
critical の入り口と出口
ordered の入り口と出口
parallel の入り口と出口
for の出口
sections の出口
single の出口
parallel for の入り口と出口
parallel sections の入り口と出口
nowait 句が指定されている場合には、ディレクティブは暗黙的に指定されません。 次のディレクティブの場合は、flush ディレクティブが暗黙的に指定されないので注意が必要です。
for の入り口
master の入り口と出口
sections の入り口
single の入り口
volatile 修飾型のオブジェクトの値にアクセスする参照は、それ以前のシーケンス ポイントにそのオブジェクトを指定する flush ディレクティブがあったかのような動作をします。 volatile 修飾型のオブジェクトの値を変更する参照は、それ以降のシーケンス ポイントにそのオブジェクトを指定する flush ディレクティブがあるような動作をします。
flush ディレクティブはその構文に C 言語ステートメントを持たないため、プログラム内に C 言語ステートメントを配置する場合にはいくつかの制限が生じます。 正しい文法については、「C. OpenMP C と C++ の文法」を参照してください。 これらの制限を次の例に示します。
/* ERROR - The flush directive cannot be the immediate
* substatement of an if statement.
*/
if (x!=0)
#pragma omp flush (x)
...
/* OK - The flush directive is enclosed in a
* compound statement
*/
if (x!=0) {
#pragma omp flush (x)
}
flush ディレクティブに対する制限は次のとおりです。
- flush ディレクティブには参照型の変数は指定できません。