std::execution::sequenced_policy,std::execution::parallel_policy,(3) | C++ Standard Libary | std::execution::sequenced_policy,std::execution::parallel_policy,(3) |
NAME¶
std::execution::sequenced_policy,std::execution::parallel_policy, - std::execution::sequenced_policy,std::execution::parallel_policy,
Synopsis¶
Defined in header <execution>
class sequenced_policy { /* unspecified */ }; (1) (since C++17)
class parallel_policy { /* unspecified */ }; (2) (since C++17)
class parallel_unsequenced_policy { /* unspecified */ }; (3) (since
C++17)
class unsequenced_policy { /* unspecified */ }; (4) (since
C++20)
1) The execution policy type used as a unique type to disambiguate parallel
algorithm overloading and require that a parallel algorithm's execution may
not be
parallelized. The invocations of element access functions in parallel
algorithms
invoked with this policy (usually specified as std::execution::seq) are
indeterminately sequenced in the calling thread.
2) The execution policy type used as a unique type to disambiguate parallel
algorithm overloading and indicate that a parallel algorithm's execution may
be
parallelized. The invocations of element access functions in parallel
algorithms
invoked with this policy (usually specified as std::execution::par) are
permitted to
execute in either the invoking thread or in a thread implicitly created by
the
library to support parallel algorithm execution. Any such invocations
executing in
the same thread are indeterminately sequenced with respect to each other.
3) The execution policy type used as a unique type to disambiguate parallel
algorithm overloading and indicate that a parallel algorithm's execution may
be
parallelized, vectorized, or migrated across threads (such as by a
parent-stealing
scheduler). The invocations of element access functions in parallel
algorithms
invoked with this policy are permitted to execute in an unordered fashion in
unspecified threads, and unsequenced with respect to one another within each
thread.
4) The execution policy type used as a unique type to disambiguate parallel
algorithm overloading and indicate that a parallel algorithm's execution may
be
vectorized, e.g., executed on a single thread using instructions that operate
on
multiple data items.
During the execution of a parallel algorithm with any of these execution
policies,
if the invocation of an element access function exits via an uncaught
exception,
std::terminate is called, but the implementations may define additional
execution
policies that handle exceptions differently.
Notes¶
When using parallel execution policy, it is the programmer's
responsibility to avoid
data races and deadlocks:
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
});
Unsequenced execution policies are the only case where function calls are
unsequenced with respect to each other, meaning they can be interleaved. In
all
other situations in C++, they are indeterminately-sequenced (cannot
interleave).
Because of that, users are not allowed to allocate or deallocate memory,
acquire
mutexes, use non-lockfree std::atomic specializations, or, in general,
perform any
vectorization-unsafe operations when using these policies
(vectorization-unsafe
functions are the ones that synchronize-with another function, e.g.
std::mutex::unlock synchronizes-with the next 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;
});
If the implementation cannot parallelize or vectorize (e.g. due to lack of
resources), all standard execution policies can fall back to sequential
execution.
See also¶
seq
par
par_unseq
unseq global execution policy objects
(C++17) (constant)
(C++17)
(C++17)
(C++20)
2022.07.31 | http://cppreference.com |