2012-11-20 4 views
2

스레드 A에서 업데이트되고 다른 스레드에서 읽는 메모리 변수가 있습니다. 값이 0이 아닌 경우 독자 만 신경을 씁니다. 일단 값이 증가하면 결코 0으로 되돌아 가지 않습니다. 아래와 같이 최적화하는 것이 합리적입니까? 다른 말로하면, 독자의 입장에서 볼 때, 나는 만족스러운 상태가되면 "울타리"가 필요 없다. 당신이 실제로 응용 프로그램의 성능을 측정 기본 (순차적으로 일관) 아토를 사용하여 시도하지 한 경우C++ 원자 적 순서 효율성

std::atomic<int> counter; 

writer: 
increment() 
{ 
    counter.store(counter+1, std:memory_order_release) 
} 

reader: 
iszero() 
{ 
    if (counter.load(std::memory_order_relaxed) > 0) return false; 
    // memory fence only if condition not yet reached 
    return (counter.load(std::memory_order_acquire) == 0); 
} 
+1

카운터가 0으로 돌아갈 수 있습니다. –

+0

reader :: iszero()는 스레드 로컬 부울 값을 가지며 카운터에서 처음으로 0이 아닌 값을 반환합니다. 그것이 사실이라면 즉시 false를 반환하십시오. 그래도 틀린 경우에만 카운터를 확인하십시오. –

+0

독자는 얼마나 자주 전화를 받습니까? 조숙 한 최적화 같아 보인다. –

답변

2

는 첫째, 내가 다시 돌려 좋을 것, 그것을 프로파일, 그 성능 문제의 원인이 관찰 표시 지금.

그러나, 당신이 정말로 ... 편안한 아토에 대해 추론을 시작해야하는 경우가 거의 확실 x86에서 작동하지만, 당신이 무엇을 기대해야 할 보장되지


.

다른 비 원자 데이터의 게시를 보호하기 위해이 방법을 사용하고 있습니다. 이 경우

, 당신은 즉, 당신이있어 데이터를 초기화 ( 경우, 독자 스레드에서 비 원자 메모리 위치에 다음 다양한 부작용이 아닌 값을 읽을 수 있다는 보장이 필요 게시하기 전에 저장소에있는 작성자 스레드에서 만든 내용은 판독기 스레드에서 볼 수 있습니다.

std::memory_order_relaxed와 비제로 읽는 것은하지 않습니다 코드는 위의이 보증을하지 않도록 std::memory_order_release 저장소와 동기화 할 수 있습니다.

내가 설명한 동작을 얻으려면 std::memory_order_acquire을 사용해야합니다. x86을 사용하는 경우 acquire는 메모리 펜스 명령어를 생성하지 않으므로 성능이 memory_order_relaxed과 다른 유일한 방법은 일부 컴파일러 최적화를 방지하는 것입니다.

+0

우선, 제 경우에는 원자 위치의 새로운 0이 아닌 값을 신경 쓰는 경우에만 비 atmoic 위치에 관심이 있습니다. 나는 x86 명령어를 점검했다. 바로 당신이 인수와 완화 사이에 차이가없는 것 같다. 둘 다 mov를 사용한다. 모든 상점을 순서대로 볼 수 있다는 보증 만 요구합니다. 나는 릴리스와 함께 더 가벼운 지시 - 세트를 얻을 수 있었으면 좋겠다. – excalibur

관련 문제