컴파일러가 사기를 친다.
release 모드는 컴파일 시 최적화를 진행한다.
멀티 쓰레드 환경에서 각 쓰레드가 공용 변수(전역변수)를 사용함에 있어서 자주 사용하는 변수를 캐시에 넣고 빠르게 사용 할 수 있다. (최적화 기능)
문제는 여러 쓰레드가 공용변수를 각자의 사용중인 코어의 레지스터에서 가져다 쓸때 , 어떤 한 쓰레드가 공용 변수를 수정 했더라도 다른 쓰레드에선 반영이 안될 수 있다는 것.
즉, 나는 분명 변수를 수정했는데 다른 쓰레드에서 수정 전의 값을 사용한다.
따라서 반드시 변수를 메모리에 읽고 쓰게끔 해야한다. 즉, volatile 변수를 참조할 경우 레지스터에 로드된 값을 사용하지 않고 매번 메모리를 참조
그래서 존재하는것이 volatile 키워드.
volatile은
- 변수에 대해서 반드시 메모리를 읽고 쓴다.
- 따라서 변수의 변화를 다른 쓰레드에서 무조건 캐치할 수 있다.
+ 사용시 유의점
포인터 변수에 volatile적용하기.
volatile int* num;
*num = 1; //num포인터가 가르키고 있는 변수의 값 변화는 최적화로인한 오동작 X
num = other; //num포인터가 가르키고 있는 변수의 변화는 최적화로인한 오동작 O
이유는 num이 가르키고 있는 변수(*num)가 volatile 이고, num은 volatile이 아니기 때문.
포인터가 volatile하도록 하고 싶으면
int* volatile num;
어느쪽이 volatile이 필요한지 잘 몰라서 두 쪽 다 volatile을 넣게되면, 한쪽은 최적화 해도 되는데 안하게 되기때문에 성능에 손해를 봄.
따라서 volatile이 필요한 곳을 확실히 해야 한다.
'멀티 쓰레드' 카테고리의 다른 글
데드락 (deadlock, 교착상태) (0) | 2023.09.06 |
---|---|
프로세스와 스레드 (0) | 2023.08.23 |
[cpu의 사기 2] atomic (0) | 2023.03.02 |
[cpu의 사기 1] alignas (0) | 2023.03.01 |