🛠 C, C++/시스템

원자성 연산, atomic

또디기 2025. 3. 23. 18:32

원자성 연산이란?

더이상 쪼개질 수 없는 연산. 다른 스레드가 끼어들기 전에 '전부 처리하거나' 또는 '아무것도 하지 못 하는' 두 가지 상태만이 존재할 수 있는 연산을 말한다.

즉 별도의 조치 없이도 경쟁 상태나 메모리 가시성 문제가 발생하지 않는 연산.

메모리 가시성 문제
메모리 값의 갱신은 한 틱만에 발생하지 않으며 일반적으로 중간다리를 거쳐 이루어진다. 예컨대 스레드A가 메모리 0x01 주소의 값에 11을 기록하려고 '일련의 입력 프로세스'에 진입했는데, 그 밑에서 생성된 스레드B는 아직 입력 프로세스가 끝나지 않아 새 값이 기록되기 전의 메모리를 읽어들일 수 있다.
비슷한 문제로 코드 재배치 문제도 있다. 컴파일러는 딱히 멀티스레드 환경을 고려해 로우 레벨 코드를 생성하지 않기 때문에 그게 더 효율적이라는 이유로 '멀티스레드 환경에선 문제가 되는 방향으로' 코드의 순서를 뒤바꿔버릴 수도 있다. 심지어는 컴파일러가 아니더라도 CPU가 명령을 실행할 때 순서를 바꿀 수도 있다. CPU가 하나의 명령을 처리하는 것조차 한 틱만에 일어나는게 아니다.

 

C++에서는 std::atomic<T> 템플릿 객체로 변수를 감싸면 해당 변수에 대한 연산을 원자성 연산으로 처리해준다. Primitive Type에 대해선 당연히 가능하지만, 유저가 정의한 타입은 복잡한 제약조건이 있고 원자성 연산이 성립을 하더라도 조건에 따라 성능은 달라질 수 있다고 한다.

 

더 공부가 필요!