개요

test and test and set은 기존 Test and set의 단점을 극복하기 위해서 만들어졌다. 모든 test_and_set은 기존의 val값이 무었이든 상관없이 cache line invalidation을 요구한다. 이는 Multicore환경에서 performance저하를 일으켜서 Scalability을 저하시킨다. 이 문제를 해결하기 위해서 Test and test and set은 우선 set없는 test를 수행하여 변수를 확인하고 특정조건에서만 test and set을 요구한다.

class TasSpinLock
{
public:
    ALWAYS_INLINE void Enter()
    {
        // atomic_bool::exchange() returns previous value of Locked
        while (Locked.exchange(true, std::memory_order_acquire) == true);
    }
 
    ALWAYS_INLINE void Leave()
    {
        Locked.store(false, std::memory_order_release);
    }
 
private:
    alignas(CACHELINE_SIZE) std::atomic_bool Locked = {false};
};
 
static_assert(sizeof(TasSpinLock) == CACHELINE_SIZE, "");

단점

  1. Thundering Herd문제가 역시 발생한다. 이 문제를 해결하고자 임의의 (혹은 여러 파라미터로 결정되는 시간의) backoff즉 지연을 주어서 각 스레드가 특정한 지연뒤에 TTAS를 실행시키도록 하는 방법도 있다. 이 방식을 TATAS with exponential backoff라고 한다.

참고

  1. https://geidav.wordpress.com/tag/test-and-test-and-set/