[C++] 메모리 모델

seunghyun·2023년 3월 28일
0

Server

목록 보기
1/4

C++ 11 에서 업데이트된 것 중 제일 중요한 점은 메모리 모델에 대한 내용이 확립된 점 같다.

Memory model (정책) 에서 우리가 넣어주는 여러 옵션이 이렇게 크게는 3가지로 분류할 수 있다.
1) Sequentially Consistent (seq_cst ; 일관성이 있다)
2) Acquire-Release (acquire, release, acq_rel)
3) Relaxed (relaxed)

간단히 살펴보자면 아래와 같다. 정책에 따라 가시성과 코드 재배치 문제의 해결 여부에 있어서 차이가 있다.
1) seq_cst : 가장 엄격하다. 컴파일러 최적화 여지가 적다. 직관적이다. 기본 옵션이다!
2) acquire-release
3) relaxed : 자유롭다. 컴파일러 최적화 여지가 많다. 직관적이지 않다.


여러 쓰레드가 동일한 메모리가 동시 접근, 그 중에서도 write 연산을 하면

  • Race Condition (경합 조건) 이 일어난다.
    그러면 Undefined Behavior 라는 언어 차원에서 보증할 수 없는 상황이 발생한다.

공유 자원에 동시 접근하게 되면 2가지 방법을 선택할 수 있다.

1) Lock (표준 뮤텍스) 을 걸어서 상호 배타적으로 접근해서

  • 나 먼저 접근하고 내가 끝나면 너가 접근해~ 이렇게 순서를 정해서 접근한다.

2) atomic 한 연산 (all or nothing) 으로 해결할 수 있다.

  • 사실 원자적 연산으로 한다고 해서 보증되지 않는다. (가시성, 코드 재배치 문제가)
    • atomic 연산에 한해, 모든 스레드가 동일 객체에 대해서 동일한 수정 순서를 관찰 한다는 것이 절대 법칙이다.
    • 이 말이 어떤 의미일까?
    • '절대 시간' 예시를 생각하면 좋다!
    • '밤하늘의 별' 을 관찰한다고 생각해보자. 우리 눈엔 보이는 건 당장의 모습이 아니라 사실 사라진 별일 수 있다. 그러나 미래의 별은 절대 볼 수 없다.

int main()
{
	atomic<bool> flag = false;
    // flag.is_lock_free(); // false 라면 락을 걸어야 한다는 뜻
    flag.store(true, memory_order::memory_order_seq_cst);
    bool val = flag.load(memory_order::memory_order_seq_cst);
}

0개의 댓글