NeuroWhAI의 잡블로그

[C++] execution policy - seq, par, par_unseq 본문

개발 및 공부/언어

[C++] execution policy - seq, par, par_unseq

NeuroWhAI 2018. 3. 4. 18:58


아래 링크는 읽어보시면 좋을 것들.


C++17에 추가된 표준이라고 합니다.
다 테스트는 안해봤는데 아직 제대로 지원하는 컴파일러를 못찾았습니다.

직역하면 '실행 정책'이 되겠네요.
알고리즘을 순차적으로 실행할지 병렬적으로 실행할지 선택권을 줍니다.
예를 들어서 C++17 버전의 std::sort를 보면


이렇게 ExecutionPolicy를 받는 버전이 추가됬는데
여기에 어떤 정책을 넣어주냐에 따라서 알고리즘의 실행 방식을 지정해줄 수 있게 됩니다.
다만 inline 키워드의 동작처럼 par로 지정한다고 꼭 병렬로 되는건 아니라는걸 유의.

레퍼런스의 for_each 예제를 봅시다.


위 코드의 결과는 아마 x가 2가 되겠죠.
실행 정책을 std::execution::par로 했습니다.
때문에 ++x가 병렬로 실행되어 Race가 일어날 수 있으므로 mutex를 사용해 동기화하는 코드가 있습니다.
par 대신 seq를 하면 그냥 없는거랑 같게 동작합니다.
그런데 par_unseq는 뭘까하는 의문이 듭니다.
둘로 충분한거 같은데....

스택오버플로의 글에 따르면 par_unseq는 알고리즘을 par보다 더 최적화 시킬 수 있도록 허용한다고 합니다.
때문에 아래 코드를 작성하면 안된다고 하네요.


단순히 par처럼 병렬로 실행된다고 생각하면 문제가 없는 것 같지만
par_unseq는 한 스레드에서 병렬 실행이 가능하도록 하기위해서 코드를 펼친다고 합니다.
(코드를 펼친다는게 저도 이해가 부족해서 설명을 못하겠습니다 ㅠㅠ)
그러니까 코드의 실행 순서가 아래처럼 섞이게 됩니다.


그럼 두번째 lock에서 데드락이 발생하게 되지요.
이걸 피하려면 아래처럼 mutex 대신 atomic을 써서 연산하면 회피할 수 있다고 합니다.


atomic의 연산은 한 명령어에서 끝나니까요.


제가 내린 결론은 성능이 그렇게 중요하지 않거나 잘 모르겠으면 seq를 쓰고
좀 중요하면 par를 쓰면서 동기화를 신경쓰고
극도로 중요한데다가 코드가 펼져지는거(vectorized)에 safe하면 par_unseq를 쓴다...
이러합니다.




Comments