2011-02-02 2 views
7

현재 초안에서 발췌 한 내용은 다음과 같습니다.C++ 0x | 왜 std :: atomic가 휘발성 한정자로 각 메소드를 오버로드합니까?

namespace std { 
    typedef struct atomic_bool { 
     bool is_lock_free() const volatile; 
     bool is_lock_free() const; 
     void store(bool, memory_order = memory_order_seq_cst) volatile; 
     void store(bool, memory_order = memory_order_seq_cst); 
     bool load(memory_order = memory_order_seq_cst) const volatile; 
     bool load(memory_order = memory_order_seq_cst) const; 
     operator bool() const volatile; 
     operator bool() const; 
     bool exchange(bool, memory_order = memory_order_seq_cst) volatile; 
     bool exchange(bool, memory_order = memory_order_seq_cst); 
     bool compare_exchange_weak(bool&, bool, memory_order, memory_order) volatile; 
     bool compare_exchange_weak(bool&, bool, memory_order, memory_order); 
     bool compare_exchange_strong(bool&, bool, memory_order, memory_order) volatile; 
     bool compare_exchange_strong(bool&, bool, memory_order, memory_order); 
     bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst) volatile; 
     bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst); 
     bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst) volatile; 
     bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst); 
     atomic_bool() = default; 
     constexpr atomic_bool(bool); 
     atomic_bool(const atomic_bool&) = delete; 
     atomic_bool& operator=(const atomic_bool&) = delete; 
     atomic_bool& operator=(const atomic_bool&) volatile = delete; 
     bool operator=(bool) volatile; 
    } atomic_bool; 
} 

휘발성은 추이입니다. 따라서 휘발성 객체에서 비 휘발성 멤버 함수를 호출 할 수 없습니다. 반면에 비 휘발성 객체에서 휘발성 멤버 함수를 호출하는 것은 허용됩니다.

따라서 원자 클래스의 volatile 및 non-volatile 멤버 함수 사이에 구현 차이가 있습니까? 즉, 비 휘발성 과부하가 필요합니까?

+0

더 좋은 질문은 처음에는 '휘발성'오버로드가 필요한 이유입니다. – GManNickG

+1

@GMan : 그렇지 않으면 함수가 휘발성 데이터에서 호출 될 수 없기 때문입니다. ;) – jalf

+3

@ jalf : 하, 그렇습니다.하지만 타입 자체가 만드는 연산은 원자 적이며 따라서 관찰 할 수있는 것이기 때문에 왜 우리는 휘발성 원자 를 만들까요? 나는 메이저 무언가를 놓치고 있다고 생각한다. – GManNickG

답변

4

나는 휘발성 과부하가 효율성을 이유로 존재한다고 생각한다. 휘발성 읽기 및 쓰기는 본질적으로 C++ 0x의 비 휘발성 읽기 및 쓰기보다 비용이 높습니다. 메모리 모델은 휘발성 변수의 값 캐싱을 방지하는 몇 가지 엄격한 요구 사항을 제시하기 때문입니다. 모든 함수가 휘발성으로 만 표시 되었다면 코드는 반드시 성능을 향상시키는 특정 최적화를 수행 할 수 없습니다. 이러한 구분을 가짐으로써 컴파일러는 가능한 경우 비 휘발성 읽기 및 쓰기를 최적화 할 수 있으며 휘발성 읽기 및 쓰기가 필요할 때 정상적으로 저하됩니다.

+1

volatile 한정자는 컴파일러 최적화를 막습니다. 게다가, 내가 아는 한 volatile 멤버는 멤버 함수에 적용된 휘발성 한정자는 휘발성 오브젝트에서만이 메서드를 호출 할 수 있으며 결과 코드에는 영향을 미치지 않습니다. – 0xbadf00d

+4

@ FrEEzE2046- C++ 0x에서 '휘발성'의 정의는 훨씬 엄격하게 지정되며 실제로 "최적화하지 마십시오."이상의 의미를 갖습니다. 또한, 멤버 함수에서의 volatile 수정 자의 더 정확한 의미는'this' 포인터가'volatile'이므로, 함수에서 발생하는 멤버 변수에 대한 모든 액세스는 암시 적으로 volatile이됩니다. – templatetypedef

+0

휘발성 멤버 함수를 호출 할 때 객체가 최적화되지 않습니까? (휘발성 객체에 대한 액세스는 추상 기계의 규칙에 따라 엄격하게 평가됩니다.) – 0xbadf00d

-1

우선 휘발성 std :: atomic을 만들기 위해 여분의 소리가납니다. 사실, 나는 유용한 상황을 상상할 수있다. 우리는 고정 장치 (메모리) 주소를 가지고 있다고 가정합니다. std :: atomic_xxx 클래스뿐만 아니라 std :: atomic <> 템플릿 클래스 크기가 해당 기본 제공 형식과 동일한 크기 여야하기 때문에 두 가지를 모두 처리해야 할 수 있습니다. 메모리 순서와 우리의 원자 개체에 대한 액세스가 절대 최적화되지 않았는지 확인하십시오. 따라서 다음과 같이 선언 할 수 있습니다.

std::atomic<long> volatile* vmem_first4 = reinterpret_cast<std::atomic<long> volatile*>(0xxB8000); 
+0

표준에서는 '원자 '은 동등한 크기를 가질 수 없다고 명시되어있다. 'T' – jalf

+1

'원자 주소 형식의 표현은 해당 정규 형식과 같은 크기 일 필요는 없으며 항상 같은 크기 여야한다. 가능한." 그래서 휘발성 원자 은 나에게 쓸모없는 것처럼 보인다. – 0xbadf00d