그린티라떼
개발공간
그린티라떼
전체 방문자
오늘
어제
  • 분류 전체보기 (26)
    • unity (6)
      • 개발 (4)
      • iTween (0)
      • error (2)
    • 게임서버 (5)
    • C++ (7)
      • 문법 (5)
      • 알고리즘 (2)
    • C# (5)
    • CS지식 (1)
    • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 유니티
  • 정규 표현식
  • 함수 호출 오버헤드
  • object
  • 일반화컬렉션
  • C++
  • 제네릭
  • Container
  • 일반화
  • interface
  • property
  • 메모리영역
  • delegate chain
  • 데이터타입
  • Functions
  • inline 함수
  • var
  • regex
  • unity
  • 다중상속의 문제점
  • 컨테이너
  • Dynamic
  • Gradle build failed
  • 형식매개변수의 제약
  • 함수호출
  • c#
  • Delegate
  • 유니티 빌드 에러
  • cout 스트림 버퍼
  • cs지식

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
그린티라떼

개발공간

게임서버

하드웨어 최적화

2020. 11. 30. 04:19
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 y
            r2 = y;  //Load x
        }
        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);
        }
    }

하드웨이 최적화를 알기위한 예제중 하나이다.

 

스레드 2개가 있고 각각 Store계산을 먼저하고 Load계산를 하게 만들었다. 그 후 Main()함수에서 반복문으로 스래드를 실행시키고 WaitAll()을 사용해서 두 스레드가 끝날 때까지 기다린 다음 r1과 r2가 만약 0이면 빠져나오게 만들었다.

 

스레드를 순서대로 실행을 한다면 무한루프에 빠지게 된다.

하지만 여러번 실행 결과 전부 반복문을 빠져나왔다.

 

반복문을 빠져 나올 수 있던 이유는 하드웨어가 최적화를 실행 했기 때문이다.

Thread_1() 함수안에 코드 두 줄은 서로 의존성(연관성)이 없고 하드웨어가 의존성이 없다고 판단하고 성능을 높이는 최적의 수를 찾다가 코드의 순서를 바꾼 것이다.

Thread_2 () 함수도 마찬가지로 최적화가 실행 되어서 반복문을 빠져 나올 수 있었다.

 

 

해결법

<메모리 배리어>

코드 재배치 억제, 가시성

   - Full Memory Barrier (ASM MFENCE) : Store/Load 둘 다 막는다  

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

 

   - Store Memory Barrier (ASM SFENCE) : Store만막는다

   - Load Memory Barrier (ASM LFENCE) : Load만막는다

 

 

 

 

예제2

 int _answer;
        bool _complete;
        void A()
        {
            _answer = 123;
            Thread.MemoryBarrier(); //Barrier1
            _complete = true;
            Thread.MemoryBarrier(); //Barrier2
        }
        void B()
        {
            Thread.MemoryBarrier(); //Barrier3
            if (_complete)
            {
                Thread.MemoryBarrier();  //Barrier4
                Console.WriteLine(_answer);
            }
        }

Barrier1 : _answer이 write 했다라는 억제와 가시성을 보여준다

Barrier2 : _complete가 write 했다라는 억제와 가시성을 보여준다

Barrier3 : _complete가 최신화가 되었는지 억제와 가시성을 보여준다

Barrier4 : _answer이 최신화가 되었는지 억제와 가시성을 보여준다

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

ReaderWriterLock 구현 연습  (0) 2020.12.01
캐시 이론  (0) 2020.11.30
컴파일러 최적화  (0) 2020.11.30
쓰레드 기초  (0) 2020.11.30
    '게임서버' 카테고리의 다른 글
    • ReaderWriterLock 구현 연습
    • 캐시 이론
    • 컴파일러 최적화
    • 쓰레드 기초
    그린티라떼
    그린티라떼

    티스토리툴바