메모리 베리어

Icarus_w·2022년 12월 22일
0
using System;

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}번만에 빠져 나옴!");
        }

    }
}

빠져나온 로그가 실행되는 기이한 현상이 발생한다.

하드웨어가 최적화를 실행하면서 연관성이 없는 코드의 순서가 뒤바뀌어 실행되는 경우가 있기 때문이다.
image

이를 막기위해 메모리 베리어를 사용한다.

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
}

무조건 명령을 내린 순서대로 강제할 수 있다.

종류

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만 막는다.

메모리 베리어 용도

1) 코드 재배치 억제

경계선을 만들어 순서가 바뀌지 안도록 한다.

2) 가시성

프로그램입장에서의 가시성을 말한다.

베리어 코드를 만나면 실제 메모리에 값을 올리고 , 최신 값을 불러오는 역할을 한다.

profile
하루에 하나

0개의 댓글

관련 채용 정보