c ++, std :: atomic, std :: memory_order는 무엇이며 어떻게 사용합니까?
누구나 일반 영어로 std :: memory_order가 무엇인지 설명하고 std :: atomic <>과 함께 사용하는 방법을 설명 할 수 있습니까?
여기에서 참조와 몇 가지 예를 찾았지만 전혀 이해하지 못합니다. http://en.cppreference.com/w/cpp/atomic/memory_order
감사.
누구나 일반 영어로 std :: memory_order가 무엇인지 설명 할 수 있습니까?
다양한 메모리 순서에 대해 내가 찾은 최고의 "일반 영어"설명은 Bartoz Milewski의 이완 원자에 대한 기사입니다. http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/
그리고 후속 게시물 : http://bartoszmilewski.com/2008/12/23/the-inscrutable-c-memory-model/
그러나이 기사는 좋은 소개이지만 C ++ 11 표준보다 이전이며 안전하게 사용하기 위해 알아야 할 모든 것을 알려주지는 않습니다.
std :: atomic <>과 함께 사용하는 방법?
여기에서 당신에게 가장 좋은 조언은 : 하지 마십시오 . 완화 된 원자는 (아마도) C ++ 11에서 가장 까다 롭고 가장 위험한 것입니다. 스틱 std::atomic<T>
기본 메모리 순서 (순차 일관성) 당신이 정말로 때까지, 정말 당신이 완화 된 메모리 순서 부를 사용하여 해결할 수있는 성능 문제가있다.
위에 링크 된 두 번째 기사에서 Bartoz Milewski는 다음과 같은 결론에 도달합니다.
나는 C ++ 약한 원자에 대해 추론하려고 할 때 내가 무엇을 얻고 있는지 전혀 몰랐다. 그들 뒤에 숨겨진 이론은 너무 복잡해서 경계선을 사용할 수 없습니다. 비교적 간단한 알고리즘의 증명을 완성하기 위해 세 사람 (Anthony, Hans 및 me)과 표준 수정이 필요했습니다. 약한 원 자성을 기반으로 잠금없는 대기열에 대해 동일한 작업을 수행한다고 상상해보십시오!
이 std::memory_order
값을 사용하면 원자 적 작업에서 제공하는 메모리 순서에 대한 세분화 된 제약 조건을 지정할 수 있습니다. 여러 스레드에서 원자 변수를 수정하고 액세스하는 경우 std::memory_order
값을 작업에 전달하면 해당 원자 변수에 대한 작업이 다른 스레드에 표시되는 순서와 동기화에 대한 컴파일러 및 프로세서의 제약 조건 을 완화 할 수 있습니다. 이러한 작업이 애플리케이션의 비 원자 데이터에 미치는 영향.
의 기본 순서 std::memory_order_seq_cst
는 가장 제한적이며 예상 할 수있는 "직관적 인"속성을 제공합니다. 스레드 A가 일부 데이터를 저장 한 다음를 사용하여 원자 플래그를 설정 std::memory_order_seq_cst
하면 스레드 B가 플래그가 설정된 것을 확인하면 작성된 데이터를 볼 수 있습니다. 스레드 A에 의해. 다른 메모리 순서 값은 반드시 이러한 보장을 제공하는 것은 아니므로 매우 신중하게 사용해야합니다.
기본 전제는 std::memory_order_seq_cst
(a) 자신이 무엇을하고 있는지 실제로 알고 있고 모든 경우에 편안한 사용이 안전 하다는 것을 증명할 수 있는 경우가 아니면 (기본값) 이외의 것을 사용하지 마십시오 . 그리고 (b) 프로파일 러가 완화 된 순서를 사용하려는 데이터 구조 및 작업은 병목 현상이 있습니다.
필자의 책인 C ++ Concurrency in Action 은 전체 장 (45 페이지)에서 C ++ 메모리 모델, 원자 연산 및 std::memory_order
제약 조건에 대해 설명하고 추가 장 (44 페이지)에서는 잠금없는 데이터 구조에서 동기화를위한 원자 연산 사용에 대해 다룹니다. , 완화 된 순서 제약의 결과.
Dekker의 알고리즘 과 Peterson의 상호 배제 알고리즘에 대한 내 블로그 항목 은 몇 가지 문제를 보여줍니다.
아니요. "일반 영어"설명은 32 페이지로 구성되며 여기 에서 찾을 수 있습니다 .
당신이 그것을 읽고 싶지 않다면, 당신이 연결 한 페이지는 기본값이 "항상 제정신을 행한다"-설정 인 순차적으로 일관된 순서라고 말하고 있기 때문에 메모리 순서를 잊어 버릴 수 있습니다.
당신은 다른 설정을 사용하려면 정말 읽고 위의 종이와 그것의 예제를 이해해야합니다.
간단히 말해서 컴파일러와 CPU는 작성한 방법과 다른 순서로 명령을 실행할 수 있습니다. 단일 스레드의 경우 올바르게 표시되므로 문제가되지 않습니다. 다중 프로세서에있는 다중 스레드의 경우 이것은 문제가됩니다. C ++의 메모리 순서는 컴파일러 / CPU가 수행 할 수있는 작업을 제한하고 이러한 문제를 수정합니다.
예를 들어, double-check locking 에 대한 제 기사를 살펴보면 주문이 해당 패턴을 어떻게 엉망으로 만들지 알 수 있습니다. show atomic memory ordering을 사용하여 문제를 해결할 수 있습니다.
재정렬 자체에 대해 CPU 재정렬을 고려할 수도 있습니다. 다시 말하지만 컴파일러는 재정렬도 수행 할 수 있습니다.
이 주제에 대한 모든 문서 (내 문서 포함)가 이론적 시나리오를 설명합니다. x86과 같은 가장 일반적인 CPU는 많은 명시 적 순서가 단순히 필요하지 않도록 매우 강력한 순서 보장을 제공합니다. 따라서 적절한 C ++ 11 원자를 사용하지 않더라도 코드는 여전히 작동합니다.
zvrba가 언급했듯이 주제는 실제로 매우 상세합니다. 메모리 장벽 에 대한 리눅스 커널 문서 에는 많은 세부 정보가 포함되어 있습니다.
GCC 위키에는 평범한 영어가 있습니다. ;)
http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
참고 URL : https://stackoverflow.com/questions/9553591/c-stdatomic-what-is-stdmemory-order-and-how-to-use-them
'Nice programing' 카테고리의 다른 글
android-sdk 및 sdk 폴더를 다른 드라이브로 이동 (0) | 2020.11.18 |
---|---|
reStructuredText에서 링크의 텍스트 서식 지정 (0) | 2020.11.18 |
반복되는 CSS 애니메이션 지연 (0) | 2020.11.18 |
스프레드 시트 데이터를 JSON으로 빠르고 쉽게 변환하려면 어떻게해야합니까? (0) | 2020.11.18 |
목록을 합산하는 데 mapToDouble ()이 정말로 필요합니까? (0) | 2020.11.18 |