for( 백만번 )

 i++;

 

for(백만번)

 i--;

 

해주면 결과적으로는 0이 되어야 하는데 

멀티 쓰레딩 환경에서는 그 값을 예측할 수 없다.

 


 

cpu 설계상의 이유로 

 

i++ 은 우리한테는 한 줄짜리 코드인데

 

디스어셈블 해보면 아래와 같은 명령어로 실행 된다. 

 

int32 eax = sum;

eax = eax +1;

sum = eax;

 

이 과정에서 공용자원인 i가 서로 건드리기 때문이다.

 

 

 

운영체제마다 라이브러리가 다르지만 windows 에는 interlockedAdd() 가 있지만

 

MordernC++ 표준에서는 #include<atomic> 으로 어지간해서 통합해서 사용하면 된다.

 

#include<atomic>

atomic<int32> sum = 0;

이제 sum을 누군가 사용하면 ALL-OR-Nothing 방식으로 실행된다.

 

내부적으로 어떻게 돌아가냐면 만약에 쓰레드들끼리 경합을 해서 ++를 실행하는 쓰레드가 간발의 차이로 먼저 실행했다고 한다면 사실상 경합에서 진 -- 쓰레드는 실행되지 않는다. (완료가 될때까지 살짝 대기를 하게 된다.)

 

그리고 그 순서는 CPU가 관리한다.

인스트럭션이 CPU단에 있다. 그래서 해당 sum 메모리로의 접근을 막을 수 있다.

 

 

 

아 그럼 멀티쓰레드 환경에서는 무조건 Atomic 변수를 사용하면 되겠다???

 

 

 

당연한 말이겠지만 atomic 계열을 사용하면 연산이 정말 느리다. 그래서 정말로 필요할 때만 사용해야한다. 

그리고 하나가 실행중일때 다른 쓰레드가 조금이라도 기다리니깐 병목현상이 생길 수 도 있다.

 

앞으로 배울 여러 동기화 방법중 첫번째 동기화 방법이다.

 

 

 

'C++과 언리얼로 만드는 게임 개발 > Part4. Server' 카테고리의 다른 글

★(중요_다시듣기)★DeadLock | V  (0) 2022.04.28
lock 동기화 방법(2) | V  (0) 2022.04.27
쓰레드 생성 | V  (0) 2022.04.15
환경 설정  (0) 2022.04.12
서버 OT  (0) 2022.04.12

+ Recent posts