2013-02-08 5 views
4

나는 안토니 윌리엄스가 C++ Concurrency in Action을 읽고있다. 현재 그는 내가 memory_order_consume을 담당하는 지점에 있습니다.C++ memory_order_consume, kill_dependency, dependency-ordered-before, synchronizes-with

는 블록 후이 :

지금은 메모리 순서화의 기초를 다루었으니, 그것은

그것은 나에게 조금 무서워 더 복잡한 부품 보는 시간 왜냐하면 나는 여러 가지를 완전히 이해하지 못하기 때문입니다.


의존성 순서가 이전과 동기화가 어떻게 다릅니 까? 둘 다 일찍 발생하는 관계를 만듭니다. 정확한 차이점은 무엇입니까?


나는 다음의 예에 대한 혼란 스러워요 :

int global_data[]={ … }; 
std::atomic<int> index; 
void f() 
{ 
    int i=index.load(std::memory_order_consume); 
    do_something_with(global_data[std::kill_dependency(i)]); 
} 

kill_dependency 정확히 무엇입니까? 어떤 종속성이 죽일까요? 엔티티간에? 그리고 컴파일러가 그 knowladge를 어떻게 활용할 수 있습니까?


memory_order_consume의 모든 출현을 안전하게 memory_order_acquire로 바꿀 수 있습니까? 나는. 그것은 모든 감각에서 더 엄격합니까? 리스팅 5.9에서


, 나는 안전하게

int data[5] 

std::atomic<int> data[5]; // all accesses are relaxed 

을 대체 할 수 있습니까? 나는. 획득 및 릴리스를 사용하여 비 원자 데이터에 대한 액세스를 동기화 할 수 있습니까?


그는 큐비클에있는 남자와 몇 가지 예를 통해 편안하고 획득하고 공개한다고 설명합니다. seq_cst와 비슷한 간단한 설명이 있고 소비합니까?

+0

[\ std :: kill \ _dependency \'는 무엇을 할 수 있습니까? 왜 그것을 사용하고 싶습니까?] (http://stackoverflow.com/questions/7150395/what-does-stdkill- 의존성 - do-and-why-would-want-to-use-it) – Cubbi

+0

@Cubbi, 나는 그것을 보았다 - 또 다른 예가있다. – qble

답변

2

종속성 순서가 이전과 동기화와 다른 점은 무엇입니까?

부터 1.10/10 : "[주의 : 관계는"이전과 종속 순서가 있습니다 "는"동기화와 유사 "하지만 릴리스/획득 대신 릴리스/소비를 사용합니다."

kill_dependency는 정확히 무엇을합니까?

일부 컴파일러는 데이터 종속성 분석을 수행합니다. 즉, 동기화해야 할 항목을 더 잘 파악할 수 있도록 변수의 값 변경 내용을 추적합니다. kill_dependency은 컴파일러가 이해할 수없는 코드에서 계속 진행되고 있기 때문에 더 이상 추적하지 않도록 알려줍니다.

memory_order_consume의 모든 발생은 안전하게 memory_order_acquire로 바꿀 수 있습니까? 나는. 그것은 모든 감각에서 더 엄격합니까?

나는 그렇게 생각한다. 그러나 나는 확실하지 않다.

+1

'std :: kill_dependency'는 가능한 메모리 순서 종속성 트리에서 요소를 제거하도록 컴파일러에 지시합니다. – inf

+0

"kill_dependency는 추적하지 못하도록 컴파일러에게 알려줍니다"- 예, 이해하지만 정확한 메커니즘과 모든 의미를 이해하지 못합니다. "나는 그렇게 생각한다. 그러나 나는 확실하지 않다." - 나도 그래. – qble

5

마지막 질문 옆에있는 답변에 대한 설명이 조금 더 있습니다.

  1. 시스템이 절반 하나 개의 값 반 다른의 결과를 생산, 읽기의 중간에 스레드를 전환하거나 작성할 수 있습니다 여러 스레드가 동일한 데이터에 액세스 할 때 잘못 될 수있는 세 가지가 있습니다.

  2. 컴파일러는 관련 데이터를보고있는 다른 스레드가 없다는 전제하에 코드를 이동할 수 있습니다.

  3. 프로세서는 값을 변경 한 후 주 메모리를 업데이트하거나 다른 스레드가 주 메모리의 값을 변경 한 후 다시 읽지 않고 해당 로컬 캐시에 값을 보관할 수 있습니다.

메모리 명령은 메모리 명령 인수에 따라, 아마도 3 아니라 번호 3. 원자 기능 1과 2를 해결 주소 등. 따라서 memory_order_relaxed는 "3 번으로 귀찮게하지 말라는 의미입니다. 코드는 여전히 1과 2를 처리합니다.이 경우, 적절한 메모리 정렬을 보장하기 위해 획득 및 릴리스를 사용하십시오.

2

memory_order_consume은 원자 연산 데이터에 종속적 인 모든 비 (非) 원자 연산 데이터 종속성은 해당 데이터를 사용하지 않고 표현식을 평가할 수없는 종속성입니다 (예 : x-> y에서 첫 번째없이 x-> y를 평가할 수있는 방법은 없습니다). 평가 중 x

kill_dependency는 고유 한 함수이며 다른 모든 함수는 인수에 데이터 종속성이 있습니다 .Kill_dependency는 명시 적으로는 아닙니다. 데이터 자체는 이미 동기화되었지만 가져올 표현식을 알면 나타납니다 데이터에 동기화가되지 않을 수 있습니다. 네. 귀하의 예제에서 do_something_with는 globalldata [i]의 캐시 된 값을 사용하는 것이 안전하다고 가정 할 수 있지만 실제로는 정확한 원자 값이어야합니다.

memory_order_require와 일치하는 데이터가 모두 적절하게 릴리스되면 memory_order_acquire가 엄격하게 강해 입니다.