namespace 최적화
{
class Program
{
static bool _stop = false; //동시 접근 가능
static void ThreadMain()
{
Console.WriteLine("쓰레드 시작!");
while (_stop == false)
{
//stop 신호를 기다림
}
Console.WriteLine("쓰레드 종료!");
}
static void Main(string[] args)
{
Task t = new Task(ThreadMain);
t.Start();
Thread.Sleep(1000);
_stop = true;
Console.WriteLine("Stop 호출");
Console.WriteLine("종료 대기중");
t.Wait();
Console.WriteLine("종료 성공");
}
}
}
전역 변수 _stopd은 ThreadMain()함수와 Main()함수에 접근할 수 있는 코드가 있다.
먼저 Debug 모드에서 실행을 시키면

우리가 생각했던 이러한 결과를 얻을 수 있다.
하지만 게임을 배포를 할 때 Debug모드가 아니라 Release모드로 실행해야 온갖 최적화가 되어 더 빨라지게 된다.
최적화를 많이 하게 된다는 말은 프로그램 제작할 때 디버깅이 어려워진다고 할 수 있다.
(예를 들어 Release모드는 중단점이 잘 안 먹힐 수도 있다.)

Release모드로 실행했을 때 결과이다. 무한루프에 빠진 것을 알 수 있다.

Release모드는 중단점이 잘 안 먹히지만.. 일단 while() 문에 중단점을 두고 강제로 실행시키자
중단점이 잡힌 결과가 나올 것이고
디버그 >창 >디스어셈블리 로 들어가서 어셈블리어를 살펴보면

1번 ecx 레지스터에 어떤 메모리에 있는 정보를 넣어준 것을 알 수 있다.
2번 ecx가 0인지 아닌지 체크해서
3번 만약 0이면 jump해서 다시 2번을 실행한다
즉 , test값이 0이면 계속 반복한다는 뜻이다.
즉,
if(_stop ==false)
{
while(true){}
}
이런 코드로 최적화가 된 것이다.
Release모드에서 멀티쓰래드환경에서 이러한 최적화 문제가 생긴다.
해결법)
volatile static bool _stop = false;
가장 간단하게 volatile을 붙인다. _stop은 휘발성이 된다. 즉, 최적화를 하지 못하게 한다.
* c#의 volatile은 코드상에서 최적화 x + 캐시를 무시하고 최신 값을 가지고 온다를 뜻도 있다.
* 그뿐만 아니라 c#에서 특이하게 동작하기 때문에 사용하지 않는 것을 추천한다.
'게임서버' 카테고리의 다른 글
ReaderWriterLock 구현 연습 (0) | 2020.12.01 |
---|---|
하드웨어 최적화 (0) | 2020.11.30 |
캐시 이론 (0) | 2020.11.30 |
쓰레드 기초 (0) | 2020.11.30 |