std::execution:: sequenced_policy, std::execution:: parallel_policy, std::execution:: parallel_unsequenced_policy, std::execution:: unsequenced_policy
|
헤더 파일에 정의됨
<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부터) |
병렬 알고리즘 실행 중 이러한 실행 정책 중 하나를 사용할 때, 요소 접근 함수 호출이 포착되지 않은 예외로 인해 종료되는 경우, 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)
|
전역 실행 정책 객체
(상수) |