Unity

[인프런 강의 정리] 컴파일러 최적화, 캐시이론

wny0320 2024. 9. 25. 18:57

이 글은 아래 강의를 정리한 글이다

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의 | Rookiss - 인프런

Rookiss | 네트워크/멀티쓰레드/운영체제 등 핵심 전공 지식을 공부하고 게임 서버를 바닥부터 만들어보면서 MMORPG 기술을 학습하는 강의입니다., MMORPG 개발에 필요한 모든 기술, C# + Unity로 Step By St

www.inflearn.com

해당 정리글을 한번에 보고 싶다면 아래 링크를 참조하길 바란다

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 | Notion

서버OT

mesquite-prune-8c9.notion.site


컴파일러 최적화

컴파일러가 최적화한다는 것을 알 수 있는 예시

더보기
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        static bool _stop = false;

        static void ThreadMain()
        {
            Console.WriteLine("Thread Start");

            while (_stop == false)
            {
                // _stop 될때까지 대기
            }

            Console.WriteLine("Thread End");
        }
        static void Main(string[] args)
        {
            Task t = new Task(ThreadMain);
            t.Start();

            Thread.Sleep(1000);
            // 1초 동안 대기

            _stop = true;
            Console.WriteLine("Stop Thread");
            Console.WriteLine("Stop Waiting");
            t.Wait();
            // task가 끝나는것을 기다림 Thread.Join과 같은 역할
            Console.WriteLine("Stop Success");

        }
    }
}

최적화에 대한 추가 내용들

더보기
volatile static bool _stop = false;
// 휘발성 메모리라는 의미라서 컴파일이 최적화하지 않음
// C++에도 있지만 C#에서는 캐시를 무시하고 최신값을 가져오라는 의미이기도 함
// C#에서 되게 다양하게 작동해서 사용하지 않는걸 대부분 추천

//컴파일이 최적화한다
while(_stop == false)
{
	
}
// 해당 코드를
if(_stop == true)
{
		while(true)
		{
				
		}
}
// 이런식으로 바꾼다는 의미, 릴리스에서는 자동 최적화가 들어감

캐시이론

  • 캐시 장치들의 구조
    • CPU 내부에 코어
    • 코어 내부에 ALU(연산 장치), 캐시장치
    • 캐시 장치는 레지스터, L1 캐시, L2 캐시 존재
    • RAM과 코어가 데이터를 공유
  • 캐시 철학
    • Temporal locality
      • 시간관점에서 방금 사용한 캐시에서 다시 데이터 접근할 확률이 높다
    • spacial locality
      • 공간관점에서 방금 사용한 캐시에서 그 주변 데이터에 접근할 확률이 높다
    • 이 두 개 다 운영체제에서 배운 내용

캐시 이론 실습

더보기
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] arr = new int[10000, 10000];
            {
                long now = DateTime.Now.Ticks;
                // 시간을 측정하기 위한 코드
                for(int y = 0; y < 10000; y++)
                    for(int x = 0; x < 10000;  x++)
                        arr[y, x] = 1;
                long end = DateTime.Now.Ticks;
                Console.WriteLine($"(y,x) 순서 걸린 시간 {end - now}");
            }
            {
                long now = DateTime.Now.Ticks;
                for (int y = 0; y < 10000; y++)
                    for (int x = 0; x < 10000; x++)
                        arr[x, y] = 1;
                long end = DateTime.Now.Ticks;
                Console.WriteLine($"(x,y) 순서 걸린 시간 {end - now}");
            }
            // 수학적 관점에서는 둘 다 같을 것이라고 예상됨
            // 실제 결과
            // (y,x) 순서 걸린 시간 3330848
            // (x,y) 순서 걸린 시간 4199285

            // 이유는 spacial locality 때문
        }
    }
}