본문 바로가기
게임 서버/Thread

[c#/유니티] 캐시(Cache) 이론과 메모리 배리어(Memory Barrier)

by 얘리밍 2022. 12. 6.
320x100
728x90

 

 

*  캐시(Cache)란?

          자주 사용하는 데이터나 값을 미리 복사해 둔 임시 장소이다. 

          저장공간이 작고 비용이 비싼 대신 빠른 성능 제공 

 

          장점 : 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터 접근이 가능함.

 

 

          즉, DBMS 혹은 서버에 요청하기 보다는 메모리에 데이터를 저장하여 불러다 쓴다. 

              -> DBMS의 부하가 줄어들며 성능을 높이기 위해서 사용

 

 

 

 

*  캐시(Cache) 철학

       1) 시간 지역성(temporal locality) : 가장 최근에 사용한 변수가 또 사용될 확률이 높다

       2) 공간 지역성(spacial locality) : 방금 접근한 주소와 인접한 주소의 변수가 사용될 확률이 높다 

 

 

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 }");   
}

 

 

 

 

 

실행 결과는 다음과 같다..

같은 기능을 수행하더라도 캐시의 공간 지역성으로 인해 차이가 나는 것이다. 

 

 

 

 

 


 

 

 

*  메모리 배리어(Memory Barrier)란?

         특정 연산의 순서를 강제하도록 하는 기능. CPU가 명령 순서를 지키도록 강제하여 원하는 결과를 얻도록 함. 

 

 

 

      사용 이유 ? 

 

          여러 스레드가 동시에 돌아가는 경우, 코드의 실행 순서가 바뀌는 경우가 발생할 수 있다. 

                  이 때, 다른 스레드에서 그 부분에 대한 메모리를 접근하여 잘못된 결과가 야기된다. 

 

 

     용도 


          -  코드 재배치 억제 : 컴파일러 최적화 시, 코드가 재배치 되는 것을 막는다 
          -  가시성 : 한 스레드에서 변경된 값이 다른 스레드에서 제대로 읽어지도록 함

 

 

 

  • Full Memory Barrier : Store/Load 둘 다 막는다
  • Store MeMory Barrier : Store만 막는다
  • Load Memory Barrier : Load만 막는다
       
	static int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;

        static void Thread_1()
        {
            y = 1;  //Store

            //---------------------------------------
            Thread.MemoryBarrier();
            //---------------------------------------


            r1 = x; //Load
        }
        static void Thread_2()
        {
            x = 1;
            
            //---------------------------------------
            Thread.MemoryBarrier();
            //---------------------------------------
            
            r2 = y;
        }

        int _answer;
        bool _complete;

        void A()
        {
            _answer = 123;
            Thread.MemoryBarrier();  // Barrier 1
            _complete = true;        
            Thread.MemoryBarrier();  //Barrier 2

        }

        void B()
        {
            Thread.MemoryBarrier();    //Barrier 3
            if (_complete)
            {
                Thread.MemoryBarrier(); // Barrier 4
                Console.WriteLine("_answer");
            }
        }

 

 

Barrier 1은 코드 재배치를 억제하면서 _answer 값을 없데이트함.

Barrier 2는 _complete을 업데이트 시켜주며

Barrier 3은 _complete을 확인하기 전에 읽어 값을 반영해주며

Barrier 4는 _answer 출력 전에 값을 업데이트 해주어 반영된 값이 올바르게 출력된다. 

 

 

출처 : https://www.inflearn.com/course/유니티-mmorpg-개발-part4

728x90
반응형