bool compare_exchange_weak (T& expected, T val, ..);
compare_exchange_weak()
C ++ 11에서 제공되는 비교-교환 프리미티브 중 하나입니다. 객체의 값이 같더라도 false를 반환한다는 점 에서 약 합니다 expected
. 이는 일련의 명령어 (x86의 명령어 대신)가이를 구현하는 데 사용되는 일부 플랫폼의 스퓨리어스 오류 때문입니다. 이러한 플랫폼에서 컨텍스트 전환, 다른 스레드에 의한 동일한 주소 (또는 캐시 라인) 다시로드 등은 기본 요소에 실패 할 수 있습니다. 그건 spurious
는 (동일하지 않은 객체의 값이 아니다로서 expected
동작 실패). 대신 일종의 타이밍 문제입니다.
그러나 나를 당혹스럽게하는 것은 C ++ 11 표준 (ISO / IEC 14882)에서 말한 것입니다.
29.6.5 .. 스퓨리어스 실패의 결과는 약한 비교 및 교환의 거의 모든 사용이 루프에있게된다는 것입니다.
거의 모든 용도 에서 루프에 있어야하는 이유는 무엇 입니까? 이것은 가짜 실패로 인해 실패 할 때 루프를 반복한다는 의미입니까? 그렇다면 compare_exchange_weak()
루프를 직접 사용 하고 작성 해야하는 이유는 무엇입니까? 우리는 compare_exchange_strong()
가짜 실패를 제거해야한다고 생각하는 것을 사용할 수 있습니다 . 의 일반적인 사용 사례는 compare_exchange_weak()
무엇입니까?
또 다른 질문이 있습니다. 그의 저서 "C ++ Concurrency In Action"에서 Anthony는 다음과 같이 말합니다.
//Because compare_exchange_weak() can fail spuriously, it must typically
//be used in a loop:
bool expected=false;
extern atomic<bool> b; // set somewhere else
while(!b.compare_exchange_weak(expected,true) && !expected);
//In this case, you keep looping as long as expected is still false,
//indicating that the compare_exchange_weak() call failed spuriously.
!expected
루프 상태에있는 이유는 무엇 입니까? 모든 스레드가 굶어 죽고 한동안 진행되지 않도록 방지하기 위해 있습니까?
편집 : (마지막 질문 하나)
단일 하드웨어 CAS 명령어가없는 플랫폼에서는 약한 버전과 강력한 버전이 모두 LL / SC (예 : ARM, PowerPC 등)를 사용하여 구현됩니다. 그렇다면 다음 두 루프 사이에 차이점이 있습니까? 이유가 있다면? (나에게 비슷한 성능을 가져야합니다.)
// use LL/SC (or CAS on x86) and ignore/loop on spurious failures
while (!compare_exchange_weak(..))
{ .. }
// use LL/SC (or CAS on x86) and ignore/loop on spurious failures
while (!compare_exchange_strong(..))
{ .. }
여러분 모두가 루프 내부에 성능 차이가있을 수 있다고 언급하는 마지막 질문을 드리겠습니다. C ++ 11 표준 (ISO / IEC 14882)에서도 언급됩니다.
비교 및 교환이 루프에있을 때 약한 버전은 일부 플랫폼에서 더 나은 성능을 제공합니다.
그러나 위에서 분석 한 것처럼 루프의 두 버전은 동일하거나 유사한 성능을 제공해야합니다. 내가 그리워하는 것은 무엇입니까?