2013-04-16 5 views
11

는 C++ 11 CAS 작업 (예를 들어, atomic_compare_exchange_weak, atomic_compare_exchange_strong)과 같이, 즉 두 개의 포인터와 값을 가지고 많은 : 대조적으로C++ 11 CAS 작업이 두 개의 포인터 매개 변수를 사용하는 이유는 무엇입니까?

bool atomic_compare_exchange(T* pointer, T* expected,  // pseudodeclaration! 
          T desired); 

, 마이크로 소프트, GCC, 인텔의 CAS 작업

long InterlockedCompareExchange(long* pointer, long desired,  // Microsoft 
           long expected); 

int __sync_bool_compare_and_swap (T* pointer, T expected,   // gcc and 
            T desired);      // Intel 

가 왜 C++ (11 개) CAS 기능은 두 개의 포인터를 가지고 가는가 대신 표시되는 내용의 값이 더 일반적인 하나의 포인터와 두 개의 값으로 모든 하나의 포인터와 두 개의 값을?

+0

는'__sync_bool은 _...'*는 * 부울을 반환합니다. –

+1

@KerrekSB : 인텔 매뉴얼에서 복사 한 서명을 보여주었습니다. gcc가 동일한 서명을 사용한다고 가정했습니다. 이제는 그렇지 않다는 것을 알았습니다. – KnowItAllWannabe

답변

18

C++ 11 방식이 더 유용합니다. 교환에 실패하면 *expected으로 업데이트되어이 새로운 현재 값으로 업데이트됩니다. 즉, 쉽게 루프에서 기능을 사용할 수 있습니다 :

T value = x.load(); 
T newvalue = frob(value); 

while (!atomic_compare_exchange(&x, &value, newvalue)) 
{ 
    newvalue = frob(value); 
} 

을 마이크로 소프트 서명, 작업이 GCC의 __sync_type 버전에 더 복잡하고, 저두입니다 성공 여부를 테스트. GCC의 __sync_bool을 사용하면 교환이 실패 할 때마다 다른로드를 수행해야 할 필요가 있습니다.

2

두 가지를 모두 사용하지 않는 이유는 알 수 없습니다. 제 유스 케이스에서는 C++ 버전이 덜 유용합니다. 변수가 어떤 값을 가질 때까지 기다렸다가 새로운 값으로 설정하려고합니다. GCC의 instrinsics와

:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { } 

(11) C++로 :

auto tmp = expected; 
while (!value.compare_exchange_weak(tmp,desired)) 
{ 
    tmp = expected; 
}