名前空間
変種
操作

std::execution::sequenced_policy, std::execution::parallel_policy, std::execution::parallel_unsequenced_policy, std::execution::unsequenced_policy

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
execution::sequenced_policyexecution::parallel_policyexecution::parallel_unsequenced_policyexecution::parallel_unsequenced
(C++17)(C++17)(C++17)(C++20)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
ヘッダ <execution> で定義
class sequenced_policy { /* 未指定 */ };
(1) (C++17以降)
class parallel_policy { /* 未指定 */ };
(2) (C++17以降)
class parallel_unsequenced_policy { /* 未指定 */ };
(3) (C++17以降)
class unsequenced_policy { /* 未指定 */ };
(4) (C++20以降)
1) 並列アルゴリズムのオーバーロードを明確にし、並列アルゴリズムの実行が並列化されないことを要求するために、一意の型として使用される実行ポリシー型。このポリシー(通常はstd::execution::seqとして指定される)で呼び出される並列アルゴリズムにおける要素アクセス関数の呼び出しは、呼び出し元のスレッドで不定順にシーケンスされる。
2) 並列アルゴリズムのオーバーロードを明確にし、並列アルゴリズムの実行が並列化される可能性があることを示すために、一意の型として使用される実行ポリシー型。このポリシー(通常はstd::execution::parとして指定される)で呼び出される並列アルゴリズムにおける要素アクセス関数の呼び出しは、呼び出し元のスレッド、または並列アルゴリズムの実行をサポートするためにライブラリによって暗黙的に作成されたスレッドのいずれかで実行することが許可される。同じスレッドで実行されるそのような呼び出しは、互いに不定順にシーケンスされる。std::threadまたはstd::jthreadによって作成された実行スレッドが並行順次進行保証を提供する場合、ライブラリによって作成された実行スレッドは並列順次進行保証を提供する。そうでない場合、提供される順次進行保証は実装定義である。注: 並列順次進行保証は、実行スレッドがあるステップを実行した場合、最終的に別のステップを実行することを保証し、スレッドがクリティカルセクションに入り、ロックを取得することを可能にする。これは、ロックを持っているスレッドが最終的に再度スケジュールされ、ロックを解放できるためである。
3) 並列アルゴリズムのオーバーロードを明確にし、並列アルゴリズムの実行が並列化、ベクトル化、またはスレッド間で移行(例えば、親横取りスケジューラによる)される可能性があることを示すために、一意の型として使用される実行ポリシー型。このポリシーで呼び出される並列アルゴリズムにおける要素アクセス関数の呼び出しは、未指定のスレッドで順序付けられていない方法で実行することが許可され、各スレッド内では互いに非シーケンスされる。このポリシーで呼び出される並列アルゴリズムにおける要素アクセス関数の呼び出しは、std::atomicおよびその他の並行性プリミティブを含む、標準ライブラリによって同期を行うと指定されているような、ベクトル化非安全な操作を呼び出すことは許可されない。std::threadまたはstd::jthreadによって作成された実行スレッドが並行順次進行保証を提供する場合、ライブラリによって作成された実行スレッドは弱い並列順次進行保証を提供する。そうでない場合、提供される順次進行保証は、並列アルゴリズムを呼び出すスレッドのものである。注: 弱い並列順次進行保証は、ステップを実行した実行スレッドのいずれかが最終的に別のステップを実行することを保証する。これは、ロックを持っているスレッドがロックを取得しようとしているスレッドが終了するまで再度スケジュールされない可能性があるため、スレッドがクリティカルセクションに入ったり、ロックを取得したりすることを許可しない。
4) 並列アルゴリズムのオーバーロードを明確にし、並列アルゴリズムの実行がベクトル化される可能性があること、例えば、複数のデータ項目に対して操作する命令を使用して単一スレッドで実行されることを示すために、一意の型として使用される実行ポリシー型。

これらの実行ポリシーのいずれかを使用して並列アルゴリズムを実行中に、要素アクセス関数の呼び出しが捕捉されない例外を介して終了した場合、std::terminateが呼び出されるが、実装は例外を異なる方法で処理する追加の実行ポリシーを定義してもよい。

[編集] 備考

並列実行ポリシーを使用する場合、データ競合とデッドロックを回避するのはプログラマの責任である。

int a[] = {0, 1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i)
{
    v.push_back(i * 2 + 1); // Error: data race
});
std::atomic<int> x {0};
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    x.fetch_add(1, std::memory_order_relaxed);
    while (x.load(std::memory_order_relaxed) == 1) { } // Error: assumes execution order
});
int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m);
    ++x; // correct
});

非シーケンス実行ポリシーは、関数呼び出しが互いに「非シーケンス」(すなわち、割り込み可能)である唯一のケースである。C++の他のすべての状況では、それらは不定順シーケンス(割り込み不可)である。このため、ユーザーは、これらのポリシーを使用する際に、メモリの割り当てまたは解放、ミューテックスの取得、非ロックフリーのstd::atomic特殊化の使用、または一般的に「ベクトル化非安全」な操作(ベクトル化非安全な関数とは、他の関数と同期するものであり、例えばstd::mutex::unlockは次のstd::mutex::lockと同期する)を実行することは許可されない。

int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m); // Error: lock_guard constructor calls m.lock()
    ++x;
});

実装が並列化またはベクトル化できない場合(例えば、リソースの不足のため)、すべての標準実行ポリシーはシーケンシャル実行にフォールバックすることができる。

[編集] 関連項目

(C++17)(C++17)(C++17)(C++20)
グローバル実行ポリシーオブジェクト
(定数) [編集]
English 日本語 中文(简体) 中文(繁體)