Unity

[인프런 강의 정리] 메모리 배리어

wny0320 2024. 9. 25. 19:00

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

 

[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 int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;

        static void Thread_1()
        {
            y = 1; // Store y
            r1 = x; // Load x
        }

        static void Thread_2()
        {
            x = 1; // Store x
            r2 = y; // Load y
        }
        static void Main(string[] args)
        {
            int count = 0;
            while(true)
            {
                count++;
                x = y = r1 = r2 = 0;

                Task t1 = new Task(Thread_1);
                Task t2 = new Task(Thread_2);
                t1.Start();
                t2.Start();

                Task.WaitAll(t1,t2);

                if (r1 == 0 && r2 == 0)
                    break;
            }

            Console.WriteLine($"{count}번만에 빠져나옴!");
            // 이론상 빠져나오면 안되지만 빠져나오는 현상 발생
            // 이유는 하드웨어가 최적화를 하면 코드의 순서가 바뀌는 경우 발생
            // 따라서 y = 1과 x = 1보다 r1 = x, r2 = y가 먼저 들어가는 경우가 발생
            // 따라서 r1과 r2가 0이 되는 상황이 발생
            // 멀티 쓰레드인 경우에만 발생하는 문제
        }
    }
}

메모리 배리어 설명과 실습

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

namespace ServerCore
{
    // 메모리 배리어
    // A) 코드 재배치 억제
    // B) 가시성
		// ASM : 어셈블리
    // 1) Full Memory Barrier (ASM MFENCE, C# Thread.MemoryBarrier) : Store/Load 둘다 막음
    // 2) Store Memory Barrier (ASM SFENCE) : Store만 막음
    // 3) Load Memory Barrier (ASM LFENCE) : Load만 막음
    class Program
    {
        static int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;

        static void Thread_1()
        {
            y = 1; // Store y
            Thread.MemoryBarrier();
            // 순서를 바꾸지 않게 막아주는 코드
            // 실제 메모리와 데이터 싱크
            r1 = x; // Load x
        }

        static void Thread_2()
        {
            x = 1; // Store x
            Thread.MemoryBarrier();
            // 순서를 바꾸지 않게 막아주는 코드
            // 실제 메모리와 데이터 싱크
            r2 = y; // Load y
        }
        static void Main(string[] args)
        {
            int count = 0;
            while(true)
            {
                count++;
                x = y = r1 = r2 = 0;

                Task t1 = new Task(Thread_1);
                Task t2 = new Task(Thread_2);
                t1.Start();
                t2.Start();

                Task.WaitAll(t1,t2);

                if (r1 == 0 && r2 == 0)
                    break;
            }

            Console.WriteLine($"{count}번만에 빠져나옴!");
        }
    }
}
  • 가시성
    • 쓰레드끼리 스택을 공유, 메모리에 commit, fetch 해서 서로 데이터를 공유