2016-11-17 9 views
3

fetch_add

std::atomic<int> x(0); 

가이 전 기능하고 있다고 가정하자 다음 사항을 고려하십시오 :

memory_order_relaxed 편안 작동 : description for acquire release memory ordering을 바탕으로

int x_old = x.fetch_add(1,std::memory_order_acq_rel); 

: 동기화 또는 순서 제약이 없으며 원 자성 만 있습니다. 더 판독하거나 현재 스레드의 값은 현재로드 캔에 따라 기록이 동작에 필요한

memory_order_consume (아래 편안한 순서 참조)이 기억 순서와로드 동작은 영향을받은 메모리 위치에 조작을 소비하지 수행 이로드 전에 재정렬해야합니다. 동일한 원자 변수를 해제하는 다른 스레드의 데이터 종속 변수에 대한 쓰기는 현재 스레드에서 볼 수 있습니다. 대부분의 플랫폼에서이 컴파일러 최적화에만 영향이 메모리 주문

memory_order_acquire로드 조작 (아래 주문 릴리스-소비 참조) 영향을받는 메모리 위치에서 획득 작업을 수행 : 더 읽거나 현재의 thread로 기록 할 수 이로드 전에 재정렬해야합니다. 더 읽거나에 쓴다 동일한 원자 변수를 공개 다른 스레드에서 모든 기록은 현재 스레드에 표시되어이 메모리 위해 함께 저장 조작이 해제 동작 수행

memory_order_release을 (릴리스-획득 아래 주문 없음 참조) 현재 스레드는이 저장소 이후에 재정렬 될 수 있습니다. 현재 스레드의 모든 쓰기는 동일한 원자 변수 (아래의 Release-Acquire 순서 참조)를 가져 오는 다른 스레드에서 볼 수 있으며 원자 변수에 대한 종속성을 갖는 쓰기는 동일한 원자를 사용하는 다른 스레드에서 볼 수있게됩니다 (릴리스 소비 아래에서 주문).

memory_order_acq_rel이 메모리 순서로 읽기 - 수정 - 쓰기 작업은 획득 작업과 릴리스 작업입니다. 이 스레드 이전 또는 이후에 현재 스레드의 메모리 읽기 또는 쓰기를 다시 정렬 할 수 없습니다. 동일한 원자 변수를 해제하는 다른 스레드의 모든 쓰기는 수정 전에 표시되며 수정은 동일한 원자 변수를 획득하는 다른 스레드에서 볼 수 있습니다. memory_order_seq_cst

(아래 순차적 일관된 순서 참조) 획득 동작과 해제 동작을 플러스하는 모든 스레드가 동일한 순서로 모든 변형을 관찰 존재하는 하나의 전체 순서가 모두되어이 기억 순서와 상관 연산

두 개의 별개 스레드가 동일한 x_old 값을 0으로받을 수 있습니까? 아니면 x_old이 0 중 하나에 대해서만 0으로 실행되도록 보장되며 다른쪽에 대해서는 1입니다.

x_old이 모두 0 일 수있는 경우 메모리 순서를 std::memory_order_seq_cst으로 변경하면 x_old의 고유성이 보장됩니까?

+0

메모리 순서는 관련이 없습니다. 두 개의 스레드는 동일한 값을 가질 수 없습니다 (각 스레드에서 한 번만 표현식에 도달했다고 가정). – 2501

+0

메모리 순서가 중요하지 않은 이유는 무엇입니까? 읽기 - 수정 - 쓰기 연산에 대해 보장 된 읽기 - 읽기 순서가 없기 때문에 두 스레드가 모두 acq_rel에서 동일한 x_old를 가질 수 없었습니까? –

+0

주문은 여기서 간단하게 관련이 없습니다. fetch_add에서 반환되는 처음 두 값은 항상 0과 1이지만 어떤 스레드가 어떤 값을 가져올 지 보장하지 않습니다. 선택한 memory_order에 관계없이 적용됩니다. – 2501

답변

4

2 개의 개별 스레드가 동일한 x_old 값 0을 수신 할 수 있습니까?

조작이 원자이기 때문에 가능하지 않습니다. 전체적으로 발생하거나 전혀 발생하지 않습니다.

주문은 선행/후행로드/상점과 관련이 있으며 주문이 없으므로 여기서는 주문이 부적합합니다. 즉, x.fetch_add(1, std::memory_order_relaxed);의 효과는 같습니다.

lock xadd에 관계없이 memory_order에 관계없이 lock 접두사는 원 자성과 순서를 모두 제공합니다. memory_order_relaxed의 경우 주문 번호는 lock입니다.