Namespaces
Variants

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

cppreference.net에서 가져옴
 
 
알고리즘 라이브러리
제약된 알고리즘 및 범위 알고리즘 (C++20)
제약된 알고리즘, 예: ranges::copy, ranges::sort, ...
정렬 및 관련 연산
분할 연산
(C++11)    

정렬 연산
이진 탐색 연산
(분할된 범위에 대해)
집합 연산 (정렬된 범위에 대해)
병합 연산 (정렬된 범위에 대해)
힙 연산
최소/최대 연산
(C++11)
(C++17)
사전식 비교 연산
순열 연산


 
헤더 <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에 의해 생성된 실행 스레드가 동시 진행 보장을 제공하는 경우 라이브러리에 의해 생성된 실행 스레드는 병렬 진행 보장을 제공합니다. 그렇지 않으면 제공되는 진행 보장은 구현 정의입니다. 참고: 병렬 진행 보장은 실행 스레드가 한 단계를 진행하면 결국 다른 단계를 진행할 것임을 보장합니다. 이를 통해 스레드가 임계 영역에 진입하고 잠금을 획득할 수 있습니다. 잠금을 보유한 스레드가 결국 다시 스케줄링되어 잠금을 해제할 수 있기 때문입니다.
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)
전역 실행 정책 객체
(상수)