ordered ディレクティブ
ordered ディレクティブは、並列ループ内の特定のコードブロックを、ループのインデックス順に直列的に実行させるために使用されます。これは、出力順序やデータ依存性を保証したい場合に有効です。#pragma omp for または #pragma omp parallel for に ordered 句を付与し、対象のコードブロックを #pragma omp ordered で囲む必要があります。
注:ループ本体のうち ordered ブロック以外の部分は通常通り並列実行され、順序制御の影響を受けません。
#include <iostream>
#include <omp.h>
int main() {
#pragma omp parallel for ordered
for (int idx = 0; idx < 6; ++idx) {
#pragma omp ordered
std::cout << "thread " << omp_get_thread_num()
<< " [" << idx << "]" << std::endl;
}
return 0;
}
実行結果(ordered あり)
thread 0 [0] thread 0 [1] thread 1 [2] thread 1 [3] thread 2 [4] thread 3 [5]
実行結果(ordered なし)
thread 2 [4] thread 0 [0] thread 1 [2] thread 0 [1] thread 1 [3] thread 3 [5]
master ディレクティブ
#pragma omp master は、囲まれたコードブロックをマスタースレッド(スレッド ID が 0 のスレッド)のみが実行するように指定します。他のワーカースレッドはこのブロックをスキップします。初期化処理や I/O 操作など、一度だけ実行すべき処理に適しています。
#include <iostream>
#include <omp.h>
int main() {
int total = 0;
#pragma omp parallel
{
int tid = omp_get_thread_num();
#pragma omp master
{
std::cout << "master thread id is " << tid << std::endl;
}
#pragma omp atomic
total += tid;
}
std::cout << "total = " << total << std::endl;
return 0;
}
実行結果
master thread id is 0 total = 6
barrier ディレクティブ
#pragma omp barrier は明示的な同期点を設け、すべてのスレッドがその位置に到達するまで待機させます。これにより、それ以前の操作が全スレッドで完了した後に次の処理に進むことが保証されます。for、sections、single ディレクティブの終了後には暗黙のバリアが存在します。
#include <iostream>
#include <omp.h>
int main() {
#pragma omp parallel
{
int tid = omp_get_thread_num();
std::cout << "thread " << tid << " before barrier" << std::endl;
#pragma omp barrier
std::cout << "thread " << tid << " after barrier" << std::endl;
}
return 0;
}
実行結果
thread 2 before barrier thread 0 before barrier thread 1 before barrier thread 3 before barrier thread 0 after barrier thread 2 after barrier thread 1 after barrier thread 3 after barrier