Namespaces
Variants

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

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
execution::sequenced_policy execution::parallel_policy execution::parallel_unsequenced_policy execution::parallel_unsequenced
(C++17) (C++17) (C++17) (C++20)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
定義先ヘッダ <execution>
class sequenced_policy { /* unspecified */ } ;
(1) (C++17以降)
class parallel_policy { /* unspecified */ } ;
(2) (C++17以降)
class parallel_unsequenced_policy { /* unspecified */ } ;
(3) (C++17以降)
class unsequenced_policy { /* unspecified */ } ;
(4) (C++20以降)
1) 並列アルゴリズムのオーバーロードを区別するための一意な型として使用される実行ポリシー種別で、並列アルゴリズムの実行が並列化されないことを要求します。このポリシー(通常は std::execution::seq として指定)で呼び出された並列アルゴリズムにおける要素アクセス関数の呼び出しは、呼び出しスレッド内で非決定的に順序付けられます。
2) 並列アルゴリズムのオーバーロードを区別し、並列アルゴリズムの実行が並列化される可能性があることを示すために、一意の型として使用される実行ポリシータイプ。このポリシー(通常は std::execution::par として指定される)で呼び出された並列アルゴリズムにおける要素アクセス関数の呼び出しは、呼び出し元スレッド、または並列アルゴリズム実行をサポートするためにライブラリによって暗黙的に作成されたスレッドのいずれかで実行が許可される。同じスレッドで実行されるそのような呼び出しは、互いに不確定順序でシーケンスされる。 std::thread または std::jthread によって作成された実行スレッドが並行前方進行保証を提供する場合、ライブラリによって作成された実行スレッドは並列前方進行保証を提供する。それ以外の場合、提供される前方進行保証は実装定義である。注記:並列前方進行保証は、実行スレッドが1ステップ進む場合、最終的に別のステップも進むことを保証し、スレッドがクリティカルセクションに入りロックを取得できるようにする。なぜなら、ロックを保持しているスレッドは最終的に再スケジュールされ、それを解放できるようになるためである。
3) 並列アルゴリズムのオーバーロードを区別し、並列アルゴリズムの実行が並列化、ベクトル化、またはスレッド間で移行される可能性があることを示すために、一意の型として使用される実行ポリシータイプ。このポリシーで呼び出された並列アルゴリズムにおける要素アクセス関数の呼び出しは、未指定のスレッドで順不同に実行され、各スレッド内で相互に非順序付けされることが許可されます。このポリシーで呼び出された並列アルゴリズムにおける要素アクセス関数の呼び出しは、標準ライブラリで同期のために指定されているもの( std::atomic や他の並行性プリミティブを含む)など、ベクトル化安全でない操作を呼び出すことは許可されません。 std::thread または std::jthread によって作成された実行スレッドが並行前方進行保証を提供する場合、ライブラリによって作成された実行スレッドは弱い並列前方進行保証を提供します。それ以外の場合、提供される前方進行保証は並列アルゴリズムを呼び出すスレッドのものです。注:弱い並列前方進行保証は、ステップを実行した実行スレッドの1つが最終的に別のステップを実行することを保証しますが、これはスレッドがクリティカルセクションに入ったりロックを取得したりすることを許可しません。なぜなら、ロックを保持しているスレッドは、ロックを取得しようとしているスレッドが終了するまで再スケジュールされない可能性があるためです。
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); // エラー: データ競合
});
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) { } // エラー: 実行順序を仮定している
});
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; // 正しい
});

非順序実行ポリシーは、関数呼び出しが互いに 非順序 (インターリーブ可能)となる唯一のケースです。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); // エラー: lock_guardコンストラクタはm.lock()を呼び出す
    ++x;
});

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

関連項目

(C++17) (C++17) (C++17) (C++20)
グローバル実行ポリシーオブジェクト
(定数)