NeuroWhAI의 잡블로그

[C++] Memory order 본문

개발 및 공부/언어

[C++] Memory order

NeuroWhAI 2018. 10. 16. 21:05


https://en.cppreference.com/w/cpp/atomic/memory_order

https://stackoverflow.com/questions/12346487/what-do-each-memory-order-mean

http://egloos.zum.com/sweeper/v/3059861

https://www.slideshare.net/seao/c-atomic



허.. 이런게 있을 줄은 몰랐네요.

새로 산 책에서 계속 나오는데 설명은 못알아먹겠고 ㅠㅠ

아래는 한번 정리해본 내용인데 틀린 내용 지적 부탁드립니다 ㅠ


// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
// Thread 2:
r2 = x.load(memory_order_relaxed); // C 
y.store(42, memory_order_relaxed); // D

위 코드에서 만약 memory order를 기본값(memory_order_seq_cst)으로 뒀다면

어떻게 실행이 되어도 r1 == r2 == 42가 되는 일은 없을겁니다. (그래서 이 내용을 모르고 코딩 가능)

이게 되려면 실행 순서가 D -> A -> B -> C가 되어야 하는데

Thread2의 코드 상에서 D는 C 이후에야 존재하기 때문이죠.

시퀀스 일관성이 보장된다면 그랬겠지만 relaxed ordering을 적용했기 때문에 그렇지 않습니다.

r1 == r2 == 42가 나오는 경우가 있다는 것이죠.

memory_order_relaxed는 단순히 해당 메모리 연산(load, store)의 원자성만 보장합니다.

현 스레드의 다른 메모리 연산과의 순서가 어떻게 틀어지던 상관하지 않는다는 것이기 때문에 그렇습니다.

(메모리 연산이 컴파일타임이던 런타임이던 소스코드에 적힌 순서대로 컴파일/수행되지 않을 수 있다는걸 모르셨던 분들이라면 제가 최근에 읽었던 책(링크)을 추천드립니다.)


std::atomic<std::string*> ptr;
int data;
 
void producer()
{
    std::string* p  = new std::string("Hello");
    data = 42;
    ptr.store(p, std::memory_order_release);
}
 
void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_acquire)))
        ;
    assert(*p2 == "Hello"); // never fires
    assert(data == 42); // never fires
}
 
int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}

위 코드는 Release-Acquire ordering을 사용하여 두 스레드를 동기화한 모습입니다.

(왜 release, acquire 두 종류가 쓰였냐면 그냥 release는 store 연산 전용이고 acquire는 load 연산 전용이기 때문입니다)

store(release) 덕분에 다른 메모리 쓰기 연산들(p = new ..., data = 42)이 store 이후의 위치로 reordering되지 않습니다.

또한 load(acquire) 덕분에 다른 메모리 읽기 연산들(*p2, data)이 load 이전의 위치로 reordering되지 않습니다.

그래서 consumer에서 load가 성공했다면 스레드2는 스레드1의 쓰기 작업이 모두 끝났다는걸 보장받게 됩니다.


왜 mutex 두고 atomic을 쓰냐는 생각이 드는데 뭐... 조금 빠르다네요.

게다가 가능하다면 더 느슨한 제약의 memory order를 쓰는게 더욱더 빠르고요.


...차라리 모르는게 나았을지도요.




Comments