C++ - atomic compare_exchange_weak/strong 함수
C++11 표준 라이브러리의 atomic 조작 함수 compare_exchange_weak와 compare_exchange_strong에 대한 메모.
두 함수 모두 변수의 atomic한 CAS(compare-and-swap) 작업을 제공한다. weak 버전과 strong 버전의 동작 사양은 weak 버전에서는 “교환 가능한 경우라도 CAS 조작 실패 할 가능성이 있다(spurious failure)”가(* 1), strong 버전에서는 “교환 가능한 경우 항상 CAS 작업이 성공”이라는 점만 다르다.
처음에는 weak로만 정의되어 있었지만, 강한 CAS 조작 명령을 가진 하드웨어 성능을 살리기 위해 N2748에서 strong 버전이 추가 되었다.
이용 지침은 다음과 같다. 대부분의 경우에는 루프 구조 + compare_exchange_weak에서가 좋다.
- 알고리즘 상, CAS 작업을 루프로 묶을 필요가 있으면 compare_exchange_weak를 이용한다. (예 : 일반적인 Lock-Free 알고리즘 구현 등)
- 알고리즘 상의 제약이 없고, 또 spurious failure를 허용하지 않는 경우 compare_exchange_strong을 이용한다. (예 : pthread spinlock 상당의 trylock 조작 구현(* 2) )
*1:PowerPC나 ARM 등의 LL/SC 명령을 제공하는 아키텍처의 경우, compare_exchange_weak는 하드웨어의“약한 LL/SC 명령”으로 구현된다. wikipedia:en:Load-link/store-conditional, wikipedia:Load-Link/Store-Conditional 등을 참조.
*2:C++11 표준 mutex의 try_lock 조작 시멘틱스라면 내부 구현을 compare_exchange_weak로 해도 좋다.
이 글은 2020-01-23에 작성되었습니다.