C#
C# 메모리 베리어.
comwitch
2023. 6. 16. 10:54
C#에서 멀티쓰레딩을 할 때, 각 쓰레드마다 접근 정보를 최신화하는 방식 중 하나로 메모리 베리어가 있다.
하드웨어가 서로 영향을 미치지 않는 연산이 있으면 어셈블리 순서를 임의로 바꿔버리는 행동을 할 때가 있다.
C#에서 제공하는 thread memory barrier는 barrier instruction중 save와 load를 양쪽다 베리어를 걸어주는 instruction이 포함되어 있다.
wekipedia를 보면 memory barrier insturction은 cpu나 compiler에게 memory operation의 순서를 제약한다고 나와있습니다.
코드 예제
// See https://aka.ms/new-console-template for more information
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ServerCore
{
//메모리 배리어
// a. 코드 재배치 억제
// b. 가시성
// 1) Full Memory Barrier s/l 둘다 막는다
// 2) Store MeMory Barrier : store만 막는다
// 3) load Memory Barrier : 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;
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);
Task.WaitAll(t1, t2);
//memory barrier가 없으면 다음 구문이 실행이 안된다.
if (r1 == 0 && r2 == 0)
break;
}
Console.WriteLine($"{count}번 만에 빠져나옴");
}
}
}