ワークキューイング・コンストラクタ

taskq プラグマ

taskq プラグマは、囲まれた作業(タスク)単位を実行する環境を指定します。 最初に、taskq プラグマを実行するすべてのスレッド間の中からで、ひとつのスレッドが選択されます。概念的には、taskq プラグマは、選択されたスレッドを実行する空のキューを生成され、その中で taskq ブロックの内側のコードシングルスレッドで実行されます。他のすべてのスレッドは、この概念キューに作業がキューイングされるのを待機します。task プラグマは、潜在的に異なるスレッドd実え行される作業単位を指定します。taskq ブロック内に task プラグマが存在すると、task ブロックの内側のコードは、taskq に関連付けられている概念キューにキューイングされます。キューイングされたすべての作業が終了し、そして taskq ブロックの最後に達すると、概念キューはなくなります。

制御構造体

多くの制御構造体は、異なる作業反復と作業生成のパターンを表しているため、ワークキューイング・モデルで並列化可能です。一般的なケースは次のものです。

while ループ

while ループの各反復における計算が独立している場合、ループ全体が taskq プラグマに対する環境になります。while ループ本体内の文が、task プラグマで指定される作業単位になります。while ループの条件と制御変数への修正は、task ブロックの外側に置かれ、データを制御変数に依存させるようシーケンシャルに実行されます。

C++ 反復子

C++ STL(標準テンプレート・ライブラリ) 反復子は、前述したwhile ループに非常に類似しています。STLにストアされるデータの演算は、すべてのデータに対する反復動作から独立しているからです。データが独立している演算の場合、その演算は、作業の反復がシーケンシャルであれば、並列に処理されます。このタイプの while ループ並列処理は、ループの標準 OpenMP* のforループワークシェアリングを一般化したものです。forループのワークシェアリングでは、ループの増分演算が反復子で、ループの本体が作業単位です。しかし、for ループ反復子の変数は、大抵クローズされたフォームを持つため、その変数は並列に処理することができ、シーケンシャルなステップを回避できます。

再帰関数

再帰関数もまた、並列に反復処理を指定するのに使用できます。そのメカニズムは、sections プラグマを使用する並列処理を指定するのに類似していますが、より柔軟性があります。taskqtask プラグマ間に任意のコードを置くことができ、関数の再帰的ネストで、taskq キューの概念ツリーをビルドできるためです。taskq プラグマの再帰的ネストは、ネストされた OpenMP 並列領域のように動作する OpenMP のワークシェアリング・コンストラクタの概念を拡張したものです。ネストされた並列領域のように、ネストされた各ワークキューイング・コンストラクタは新しいインスタンスで、1つのスレッドに検出されます。主な相違点は、ネストされたワークキューイング・コンストラクタは新しいスレッドやチームを生成しないことです。むしろチームからスレッドを再利用します。これにより、動的環境で、マルチ・アルゴリズム並列処理を容易にし、並列処理の各レベルでスレッドの数を確保する必要がなくなり、トップレベルだけで済ますことができます。その時点から、大量の作業量が内側のレベルで発生すると、外側のレベルからアイドルスレッドは、その作業の終了を支援することができます。例えば、1つのスレッドに各インカミング・リクエストを処理させ、多くのスレッドがインカミング・リクエストを待機している状態は、サーバ環境では非常に一般的です。特定のリクエストにおいて、スレッドが処理を開始する時点では、そのサイズが不明な場合があります。スレッドが、ネストされたワークキューイング・コンストラクタを使用し、内側のコンストラクタが開始された後にリクエストのスコープが大きくなると、外側のコンストラクタのスレッドは、リクエストを終了するために内側のコンストラクタに簡単に移動できます。

ワークキューイング・モデルはシーケンシャルなセマンティクスを保持するように設計されているため、同期化は taskq ブロックのセマンティクスでは固有のものです。taskq コンストラクタを検出したスレッドの taskq ブロックの完了時に暗黙的なチームバリアがあるため、taskq ブロック内で指定されたすべてのタスクの実行が終了したことを確認できます。この taskq バリアは、オリジナル・プログラムのシーケンシャル・セマンティクスを実行します。OpenMP ワークシェアリング・コンストラクタのように、依存性が存在しないこと、またはタスクブロック間、あるいはタスクブロックのコードと、タスクブロック外の taskq ブロックのコード間で依存性が適切に同期されることを確認する必要があります。

文法、セマンティクスおよび構文は、OpenMP* ワークシェアリング・コンストラクタと同じように設計されています。OpenMP ワークシェアリング・コンストラクタで有効な構文のほとんどは、ワークキューイング・プラグマでも、適切な意味を持ちます。

taskq コンストラクタ

#pragma intel omp taskq [clause[[,]clause]...]

     structured-block

 

clauseは次のいずれかです。

private

private 構文は、taskqvariable-list にある各オブジェクトの default-constructed バージョンの private を生成します。囲まれた各タスクで、captureprivate も含みます。各変数に参照されるオリジナルのオブジェクトは、コンストラクタに入る時点で中間値を持ちます。コンストラクタの動的範囲内では、オブジェクトは変更してはいけません。そして、コンストラクタから出る時点で中間値を持ちます。

firstprivate

firstprivate 構文は、taskqvariable-list に各オブジェクトにある copy-constructed バージョンの private を生成します。囲まれた各タスクで、captureprivate も含みます。各変数に参照されるオリジナルのオブジェクトは、コンストラクタの動的範囲内では、変更してはいけません。そして、コンストラクタから出る時点で中間値を持ちます。

lastprivate

lastprivate 構文は、taskqvariable-list にある各オブジェクトの default-constructed バージョンの private を生成します。囲まれた各タスクで、captureprivate も含みます。各変数に参照されるオリジナルのオブジェクトは、コンストラクタに入る時点で中間値を持ちます。コンストラクタの動的範囲内では、オブジェクトは変更してはいけません。そして、タスクの実行が終了した後に、オブジェクトは囲まれた最後のタスクからのオブジェクトの値をコピー割り当てされます。

reduction

reduction 構文は、variable-list にある各オブジェクトの囲まれたタスク・コンストラクタで与えられた演算子を持つリダクション演算を実行します。operatorvariable-list は、OpenMP 仕様と同じように定義されます。

ordered

ordered 構文は、オリジナルのシーケンシャル実行順序で、囲まれた task コンストラクタで、ordered コンストラクタを実行します。ordered と結合される taskq ディレクティブには ordered 構文がなければなりません。

nowait

nowait 構文は、taskq の最後にある暗黙的なバリアを削除します。taskq コンストラクタにキューされたすべての task コンストラクタが処理される前に、スレッドは taskq コンストラクタを終了できます。

task コンストラクタ

#pragma intel omp task [clause[[,]clause]...]

structured-block

 

clause は次のいずれかです。

private

private 構文は、taskvariable-list にある各オブジェクトの default-constructed バージョンの private を生成します。変数に参照されるオリジナルのオブジェクトは、コンストラクタに入る時点で中間値を持ちます。コンストラクタの動的範囲内では、オブジェクトは変更してはいけません。そして、コンストラクタから出る時点で中間値を持ちます。

captureprivate

captureprivate 構文は、task がエンキューされた時点で、taskvariable-list に各オブジェクトにある copy-constructed バージョンの private を生成します。各変数に参照されるオリジナルのオブジェクトは、その値を保持しますが、task コンストラクタの動的範囲内では、変更してはいけません。

parallel と taskq コンストラクタの組み合わせ

#pragma intel omp parallel taskq \

[clause[[,]clause]...]

structured-block

 

clause は次のいずれかです。

Clause は、上記の OpenMP の parallel コンストラクタまたは taskq コンストラクタと同様です。