[게임서버] 메모리 배리어(Memory Barrier)란?

2022. 5. 23. 22:32·공부/게임 서버
728x90

C#으로 작성되었습니다.

using System;

namespace ServerStudy
{
    class Program
    {
        static int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;

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

        static void Thread_2()
        {
            x = 1;
            r2 = 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}번 걸림");
        }
    }
}

이런 코드를 실행시켜보자.

빠져나오는 횟수는 매번 다르지만 결국 코드에서 while문을 빠져나온다. 그런데 일반적으로 생각해보면 r1과 r2가 모두 0이 되는 경우는 나올 수 없다. t1.Start()에서 r1은 1이 됐고, t2.Start()에서 r2도 1이 됐기 때문이다. 그런데 결국 r1와 r2는 모두 0이 되어 무한 반복문에서 무사히 빠져나온다.

코드가 무한 반복문에서 탈출할 수 있는 이유는 컴퓨터의 최적화 때문이다. 컴퓨터는 최적의 성능을 추구하기 위해 코드를 순서대로 처리하는 것이 아니라 자신이 생각하는 최적의 순서로 코드 순서를 바꾸게 된다. 이 과정에서 Thread_1의 y = 1보다 r1 = x가 먼저 실행된다. Thread_2또한 x = 1보다 r2 = y가 먼저 실행된다. 여기에서 r1과 r2는 0이 되고 그 후에 y와 x가 각각 1이 된다. 

멋대로 순서를 바꾸는 컴퓨터에 대항하기 위해 우리는 메모리 배리어(Memory Barrier)라는 기능을 사용한다.

 

using System;

namespace ServerStudy
{
    class Program
    {
        static int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;

        static void Thread_1()
        {
            y = 1;
            Thread.MemoryBarrier();
            r1 = x;
        }

        static void Thread_2()
        {
            x = 1;
            Thread.MemoryBarrier();
            r2 = 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; 밑에 각각 Thread.MemoryBarrier();를 넣어주면

코드는 무한 반복문에서 빠져나오지 않고 프로그램은 영영 종료되지 않는다. 즉, 프로그램이 순서대로 실행된 것이다.

Thread.MemoryBarrier를 사용하면 함수 위에 내용이 실행되기 전에는 함수 밑의 코드가 실행되지 않는다. 이를 통해 우리는 원하는 순서를 지킬 수 있다.

 

728x90

'공부 > 게임 서버' 카테고리의 다른 글

[게임서버] 스핀락(Spinlock)이란?  (0) 2022.05.25
[게임서버] 상호배제 - Monitor.Enter, Monitor.Exit  (0) 2022.05.24
[게임서버] Interlocked란?  (0) 2022.05.24
[게임서버] Temporal locality, Spatial locality  (0) 2022.05.23
[게임서버] 스레드(Thread)란?  (0) 2022.05.23
'공부/게임 서버' 카테고리의 다른 글
  • [게임서버] 상호배제 - Monitor.Enter, Monitor.Exit
  • [게임서버] Interlocked란?
  • [게임서버] Temporal locality, Spatial locality
  • [게임서버] 스레드(Thread)란?
돌멩이수프
돌멩이수프
Information technology
  • 돌멩이수프
    WHAT DOES "IT" STAND FOR?
    돌멩이수프
  • 전체
    오늘
    어제
    • 분류 전체보기 (238)
      • 언어 (73)
        • html (3)
        • css (1)
        • java (6)
        • C (26)
        • C++ (2)
        • C# (29)
      • 공부 (7)
        • Unity (43)
        • 게임 서버 (26)
        • 네트워크 (5)
        • 데이터베이스 (7)
        • EFCore (19)
        • 기타 (14)
        • Git (5)
        • 운영체제 (1)
        • 소프트웨어공학 (21)
      • 2024-여름 (12)
      • 자기 관리 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    EFCore
    Entityfamework
    HTML
    C#
    C
    자바
    unity
    tcp
    coding
    Python
    디자인패턴
    라즈베리파이
    게임서버
    C언어
    코딩
    java
    네트워크
    유니티
    EntityFramework
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
돌멩이수프
[게임서버] 메모리 배리어(Memory Barrier)란?
상단으로

티스토리툴바