2022년 3월 3일 목요일

[c# Memory Barreir]

 using System;

using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{

    /// <summary>
    /// 하드웨어 최적화 실습
    /// 메모리 배리어
    /// A) 코드 재배치 억제 (지금나온 문제를 해결할 방법)
    /// B) 가시성
    ///
    ///
    ///
    /// 1) Full Memory Barrier (ASM MFENCE, C# Thread.MemoryBarreir) : Store/Load 둘다 막는다
    /// 2) Store Memory Barrer (ASM SFENCE) : Store만 막는다
    /// 3) Load Memory Barrer (ASM LFENCE) : Load만 막는다
    /// 실제 프로그래밍을 직접 쓰지는 않는듯
    ///
    ///
    ///
    ///
    ///
    ///
    /// </summary>
    class Program
    {
        static int x = 0;
        static int y = 0;
        static int r1 = 0;
        static int r2 = 0;



        ///비밀은 하드웨어 최적화에있다
        /// y=1 과 r1=x는 아무 연관성이 없으니까
        /// r1=x ,y=1 이순서로 진행할 가능성도 있음!!
        /// 애초에 싱글스레드에서는 아무 문제가없음
        /// 하지만 멀티스레드 환경이라서 꼬이게 될 가능성이 있음
        /// Thread.MemoryBarrier(); 이것을 사용하면 순서 최적화를 적용하지않음!

        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 cnt = 0;
            while (true)
            {
                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);

                ///분명 0,0이 나올수 없을텐데 0,0인 상태가 나온다!!
                if (r1 == 0 && r2 == 0)
                    break;
            }

            Console.WriteLine($"{cnt}번 만에 빠져나옴!");
        }
    }
}


@@@@@@@@@@@@@@@@@@@@@@@@@@@@2 번 예제@@@@@@@@@@@@@@@@

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{

    /// <summary>
    /// 하드웨어 최적화 실습
    /// 이전 예제와 다르게 매모리 베리어가 많이 들어간 이유는
    ///
    ///
    ///
    ///
    /// </summary>
    class Program
    {
        int _answer;
        bool _complete;

        void Thread_1()
        {

            ///이전경우는 write다음 바로 read를 했엇다.
            ///그러나 지금은 둘다 write만 하고있음


            ///write 하고 최신정보 업데이트!
            _answer = 123;
            Thread.MemoryBarrier(); /// Barrier 1

            ///write 하고 최신정보 업데이트!
            _complete = true;
            Thread.MemoryBarrier();/// Barrier 2
        }

        void Thread_2()
        {
            ///read 하기 전에 최신정보 업데이트!
            Thread.MemoryBarrier();/// Barrier 3
            if (_complete)
            {
                ///read 하기 전에 최신정보 업데이트!
                Thread.MemoryBarrier();/// Barrier 4
                Console.WriteLine(_answer);
            }
        }


        static void Main(string[] args)
        {
           
        }
    }
}

댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...