2016-12-24 1 views
13

OpenMP에는 원자 적 액세스에 대한 자체 지원이 있지만 C++ 11 원자를 선호하는 데에는 최소한 두 가지 이유가 있습니다. 훨씬 더 유연하며 표준의 일부입니다. 반면 OpenMP는 C++ 11 쓰레드 라이브러리보다 강력합니다.C++ 11 atomics와 OpenMP의 혼합

표준은 원자 연산 라이브러리 두 장 고유의 스레드 지원 라이브러리를 지정한다. 이것은 내가 원자 접근을위한 컴포넌트들이 사용 된 쓰레드 라이브러리와 직각 인 것이라고 믿게한다. 실제로 C++ 11 원자와 OpenMP를 결합 할 수 있습니까?


스택 오버플로에는 매우 similar question이 있습니다. 그러나 그 대답은 실제 질문에 대답하지 않기 때문에 3 년 동안 기본적으로 답을 얻지 못했습니다. 흥미롭게

+0

왜 당신은 할 수 없습니까? C++ 뮤텍스를 얻고 OpenMP를 사용하여 기다려야합니다. –

+0

@brianbeuning 글쎄, 나는 확신 할 수 없다. 그래서 내가 묻고있는 것이다. 우리가 "문제가 될 가능성이 높다"고 추측하는 연상 된 질문에 대한 의견이 있습니다.웹에서 질문에 대한 확실한 답을 찾지 못했습니다. 그래서 다시 질문을 제기했습니다. – user1494080

+3

이것은 구현이 정의한 동작이며 컴파일러마다 다를 수 있습니다. 그러나 "실용적인"답변도 있습니다. 대부분의 경우 표준 라이브러리 및 OpenMP 런타임이 동일한 컴파일러 공급 업체에서 제공되는 경우 가장 잘 작동합니다. 예를 들어 libstdC++ 및 libgomp에서 GCC를 사용하고 libC++ 및 LLVM (Intel) 런타임에서 clang을 사용합니다. Linux에서 libstdC++를 사용하는 Intel C++ 또는 macOS에서 libC++와 같이 자체 표준 라이브러리가없는 컴파일러를 사용할 때 문제가있을 수 있습니다. 나는이 경우에 문제를 보았지만 매우 드물게 보았다. –

답변

6

상기의 OpenMP 4.5 규격 (2.13.6)은 약간 애매 C++ 11 아토을 참조 이상의 특정을 갖는다 std::memory_order :

목적은 유사한 조작 C에 존재하는 경우이다 ++ 11 또는 C11, 순차적으로 일관된 원자 구조체는 C++ 11/C11에서 동일한 의미의 메모리 시퀀스을 memory_order_seq_cst로 사용합니다. 마찬가지로 비 연속적으로 일관된 원자 구조는 과 C++ 11/C11의 memory_order_relaxed 원자 연산과 동일한 의미를 갖습니다.

불행히도 이것은 단지 참고 사항이며, 함께 연주하는 것을 정의하는 것은 없습니다. 특히, 최신 OpenMP 5.0 미리보기조차 C++에 대한 유일한 규범적인 참조로 C++ 98을 여전히 언급합니다. 따라서 기술적으로 OpenMP는 C++ 11 자체를 지원하지 않습니다.

그건 그렇고, 실제로는 대부분의 시간이 실제로 작동합니다. std::atomic을 사용하면 C++ 11 스레딩보다 OpenMP와 함께 사용하면 문제가 발생할 가능성이 적습니다. 그러나 어떤 문제가 있다면 그것은 분명하지 않을 수 있습니다. 최악의 경우는 원자 적으로 작동하지 않는 원자가 될 수 있습니다. 현실적인 시나리오를 상상할 수는 있지만 심각한 문제가 발생할 수도 있습니다. 마지막 날에는 그만한 가치가 없을 수도 있습니다. 가장 안전한 것은 순수 OpenMP 또는 순수 C++ 11 쓰레드/원자가를 사용하는 것입니다.

아마도 Hristo는 이에 대해 말할만한 것이 있습니다. 잠시 동안보다 일반적인 토론을 위해 this answer을 확인하십시오. 약간 날짜가 있지만, 아직 두렵습니다.

+4

OpenMP ARB 및 ** 비공식적 인 ** 응답에 OpenMP와 다른 스레딩 패러다임 간의 상호 운용성에 대해 물어 보았습니다. 아마도 사양에 포함시키지 않을 것이지만, 대부분의 공급 업체는 Yan Zhou의 의견에 요약 된대로 올바른 작업을 수행합니다. 즉, 이러한 코드는 대부분 작동하지만 결코 이식 할 수 없습니다. –

1

이것은 현재 OpenMP 4.5에서 지정되지 않았습니다. 실제로는 대부분의 컴파일러에서 OpenMP 스레드와 함께 C++ 11 원자 연산을 사용할 수 있지만 공식 연산이 필요하지 않습니다.

GCC는 지정되지 않은 동작 때문에 최근까지 C11 원자 (C++ 11 원자와 의미가 거의 동일 함)와 OpenMP 스레드를 지원하지 않았습니다. 자세한 내용은 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65467을 참조하십시오.

OpenMP 5+는이 문제를 해결합니다. 저는이 과정에 개인적으로 관여하고 있습니다. 그러나 아직 비준되지 않았으므로 세부 사항에 대해서는 언급하지 않겠습니다.