2022년 3월 3일 목요일

[c# interlock]

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

namespace ServerCore
{

    /// <summary>
    /// interlocked
    /// 공유변수 접근시 문제점 찾기 예제
    ///
    ///
    ///
    /// ref를 붙여주는 이유 고민해보기(주소값에 있는 값만 들고와서 변경)
    /// </summary>
    class Program
    {
        static int number = 0;
        static void Thread_1()
        {
            /*for (int i = 0; i < 10000; i++)
                number++;*/

            /// atomic = 원자성 (더이상 쪼갤수 없다 최소단위다)
            /// 원자성문제라고 볼수있다
            ///
            ///
            ///
            ///
            ///데이터베이스에서도 일어날 수 있는 일이다.
            /// 상점에서 아이템 구매를 했다고 가정
            /// 플레이어골드 -=100
            /// 인벤토리 += 검
            ///
            ///
            /// 플레이어골드 -=100
            /// 서버다운
            /// 인벤토리 += 검?? 서버가 다운되서 검이 추가되지 않았음!!!
            ///

            ///집행검 User2 인벤에 넣어라 -ok
            ///집행검 User1 인벤에 빼라 - fail 하면 아이템 복사가 되버린다.
            ///





            for (int i = 0; i < 10000; i++)
            {
                /// All or Nothing //여기가 실행되면 무조건 여기 완료될때까지 진행한다.
                Interlocked.Increment(ref number);///원자적으로 보증하는 명령어 //참조값으로 넣어주는 이유-> 값으로 가져오는 순간 다른데서 사용할수 있기때문에
                ///ref 를 가져와서 무슨값인지는 모르지만 주소값에 있는 값을 가져와서 무조건 1을 늘려준다.
                ///
                ///되기는 하지만 성능에서 엄청난 손해를 보게된다



                int temp = number; ///0
                temp += 1; /// 1


                ///여기서 문제가발생 뭐가 먼저 실행될지는 모르지만
                number = temp;/// number =1
            }



        }
        static void Thread_2()
        {
            /*for (int i = 0; i < 10000; i++)
                number--;*/

            for (int i = 0; i < 10000; i++)
            {


                Interlocked.Decrement(ref number);///원자적으로 보증하는 명령어
                ///되기는 하지만 성능에서 엄청난 손해를 보게된다

                int temp = number; ///0
                temp -= 1; /// -1

                ///여기서 문제가발생 뭐가 먼저 실행될지는 모르지만
                number = temp;/// number =-1

                /// 덧셈 한번 뺄셈 한번 했는데 -1이 되는 상황이 되어버렷다
            }


        }
       



        static void Main(string[] args)
        {
            number++; /// ++ 이라는 단계가 눈으로 보기에는 한단계 이지만 어셈블리어로 보면 3단계에 걸쳐 일어난다.


            /// 이런식으로 진행된다
            /// int temp = number;
            /// temp += 1;
            /// number = temp;
            /// 이런식으로 진행된다

            Task t1 = new Task(Thread_1);
            Task t2 = new Task(Thread_2);
            t1.Start();
            t2.Start();



            Task.WaitAll(t1, t2);

            ///분명 결과는 0이 나와야 하는데 이상한 값이나온다...
            ///경합 조건때문이다!(RACE CONDITION)

            Console.WriteLine(number);
        }
    }
}

[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)
        {
           
        }
    }
}

[c# 캐시 구조]

 


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

namespace ServerCore
{

    /// <summary>
    /// 캐시작동 테스트
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            int[,] arr = new int[10000, 10000];

            ///수학적으로는 분명 같은 시간이 걸릴것이다...
            ///하지만 실제로는? 엄청난 차이가 난다
            ///space와 관련이 있다
            ///

            ///5*5배열이라고 가정
            ///[][][][][] [][][][][] [][][][][] [][][][][] [][][][][]
            ///
            ///첫번째 코드는 x부터 바꾸기 때문에
            ///[0][1][2][3][4] 이런식으로 차근차근 접근함
            ///캐시는 공간법칙때문에 [0][][][][] 에서 여기 또 접근할 것이라고 생각함
            ///그래서 캐시에 [0][][][][]을 가지고 있음
            /// 다음 접근이 [0][1][][][] 1 부분이니까 캐시히트라서 램에 다시 갈필요없이 연산함(캐시값 업데이트) 상대적으로 빠르다
            ///


            ///두번째는 [0][][][][] [1][][][][] [2][][][][]
            ///이런식으로 되서 캐시의 공간적 이점을 살릴수 없다..
            /// [0][][][][]을 캐시에 넣어둿지만 다음이 [1][][][][] 이기 때문에
            /// 속도가 느리다

            {
                long now = DateTime.Now.Ticks;
                for (int y = 0; y < 10000; y++)
                    for (int x = 0; x < 10000; x++)
                        arr[y, x] = 1;
                long end= DateTime.Now.Ticks;
                Console.WriteLine($"(y,x) 순서 걸린 시간{end-now}");
            }


            {
                long now = DateTime.Now.Ticks;
                for (int y = 0; y < 10000; y++)
                    for (int x = 0; x < 10000; x++)
                        arr[x, y] = 1;
                long end = DateTime.Now.Ticks;
                Console.WriteLine($"(x,y) 순서 걸린 시간{end - now}");
            }
        }
    }
}

[c# 컴파일러 최적화]

 using System;

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

namespace ServerCore
{

    /// 컴파일러 최적화
    /// 1.스레드는 각자 할당된 스택메모리는 각자 할당받은 스택메모리를 사용한다.
    /// 2.전역으로 선언된 변수는 모든 스레드가 공통으로 사용한다. ex) _stop변수



    ///결론
    ///Release모드에서는 코드 최적화가 일어나서 Debug모드와 다르게 실행이 안될수도있다!

    class Program
    {
        ///static bool _stop = false;/// Release모드하면 최적화의 희생양이됨
       
        volatile static bool _stop = false; /// 최적화에 포함시키지 않기 위해서는 volatile이라고 선언해주어야한다.
        ///하지만 volatile 은 그냥 사용하지 않는게 좋고 lock이나 다른거를 사용해야한다~~


        static void ThreadMain()
        {
            Console.WriteLine("쓰레드 시작!");


            ///이코드는 Release에서 에러남


            ///Realese에서의 작동방식
            ///무한 뺑뺑이가 되는 구조가 되어버렷다
            /*if (_stop == false)
            {
                while (true)
                {

                }
            }*/
            ///Realese에서의 작동방식

            while (_stop == false)
            {
                ///누군가가 stop 신호를 해주기를 기다린다.
            }


            ///컴퓨터의 생각방식


            Console.WriteLine("쓰레드 종료!");
        }
       


        static void Main(string[] args)
        {
            Task t = new Task(ThreadMain);
            t.Start();

            Thread.Sleep(1000);///1초 대기 ///1초뒤에 스레드 종료되게 만들기위해!

            _stop = true;

            Console.WriteLine("Stop 호출");
            Console.WriteLine("종료 대기중");
            t.Wait();
            Console.WriteLine("종료 성공");
        }
    }
}

2022년 3월 2일 수요일

[c# Thread]

 using System;

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

namespace ServerCore
{
    class Program
    {

        static void MainThread(object state)
        {
            for (int i=0;i<5;i++)
                Console.WriteLine("Hellow Thread!");
        }

        static void Main(string[] args)
        {
           
            ///결론 왠만하면 threadPool을 사용하고
            ///아니면 Task를 사용하면된다!
            ///Thread new는 거의 사용하지 않는다!!




            ///단기알바형식
            ///백그라운드 = true
            ///다시 돌아오지 않는 thread를 넣으면 통째로 먹통이 될수있다...
            ThreadPool.SetMinThreads(1, 1);
            ThreadPool.SetMaxThreads(5, 5);


            for (int i = 0; i < 5; i++)
            {
                ///직원이 사용할 일감을 정한다는 느낌
                //Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
                ///TaskCreationOptions.LongRunning 오래 걸릴꺼라는 것을 알려줘서 별도 처리하게 만들기
                ///

                ///만약 롱러닝테스크 설정을 안해주면 똑같이 ThreadPool이 먹통이 된다.
                Task t = new Task(() => { while (true) { } });
                t.Start();
            }

            /*///영영 돌아올수 없는 일감을 맥스치만큼 준다... 에러가 발생함!(먹통예상)
            for (int i = 0; i < 5; i++)
                ThreadPool.QueueUserWorkItem((obj) => { while (true) { } });*/


            ///정확히 먹통이 안됨!
            ThreadPool.QueueUserWorkItem(MainThread);
           



            /*Thread t = new Thread(MainThread); ///너무 무겁다 정직원이다
            t.Name = "TestThread";
            t.IsBackground = true; ///백그라운드로 돌리면 메인이 떨어지면 같이 떨어진다!!
            t.Start();
            Console.WriteLine("Waiting for Thread");
            t.Join(); ///이 thread가 종료되지 않으면 밑에 것이 실행되지 않는다

            Console.WriteLine("Hello World!");*/

            while (true)
            {

            }
        }
    }
}

2022년 3월 1일 화요일

[와디즈] 돈맹스쿨 탁쌤 전자책 후기

 평소 투자 및 IT 신제품에 관심이 많았던 나는 가끔 심심하면 와디즈를 둘러보곤 했습니다.




그러던 와중

[재테크 책 100권 압축] 주식, 부동산, 창업 트라이앵글 이론 2.0

라는 펀딩이 올라온 것을 보고 궁금함에 클릭을 해보았습니다.

(책 100권 압축이라니... 얼마나 쓸데없을까라고 생각하면서 클릭했다...)




탁쌤이라는 분이 어떻게 사셨고 현재 어떻게 됐는지 사이트에 설명이 나와있었는데



왠지 사기라는 느낌보다는 정겹다고 해야 할 정도의 친절한 설명에 이끌려



비싸지도, 그렇다고 싸지도 않는 7만 9천 원가량의 돈으로 펀딩에 참여했습니다.



엄청난 기대보다는 현재 하는 주식에 조금이라도 도움이 될만한 지식을 얻어보자는 느낌으로 책을 기다렸고 받아서 읽었습니다.



책 초반부 친절하게 자본 지식을 알려주는 부분은 숫자가 많이 나와서



어려워했지만 중간부터 관심 있어 하는 테마인 주식이 나오고


자금 흐름을 만들 수 있는 여러 가지 방법이 나오는 동안 적지 않은 인사이트를 받았습니다.


그러다 후반부 한 번도 생각해 보지 않았던 부동산에 대한 지식을 알려주는 후반부에는 정말 신세계를 경험했습니다.



현재 결혼을 1년 정도 앞둔 예비 신랑으로써 집값이 많이 오른 지금



집을 구하는 게 생각만큼 녹록지 않아서 고민이 많았던 차에



부동산 경매 앱을 다운로드해서 지금 사는 지역을 확인해 보았습니다.



분명 다방이나 다른 부동산 앱에는 매물이 없었지만



경매에는 매물이 있어서 신기해하며 책을 계속 읽어 나갔습니다.



다 읽고 나니 직장인인 저도 가능성이 있는 것 같아 가슴이 뜨거워지며 열정이 올라오는 것을 느꼈습니다.



7만 9천 원이라는 거금으로(내 기준) 책을 샀지만 하나도 정말 단 1도 아깝지 않았습니다.



결론


사회 초년생, 심지어 학생에게도 매우 유용한 책이라고 생각되어

누구든 강력 추천합니다. 꼭 한번 읽고 돈맹 스쿨 탁쌤의 인사이트를 느껴보셨으면 좋겠습니다.

감사합니다.








2022년 2월 23일 수요일

activitylog.xml visual studio 2019 error

 unity 프로젝트의 아무 script를 실행시켜도 이런에러가 계속 발생해서 디버깅이 너무힘들어

고치기로 했다.(참고 계속 한 나도 대단;;)



(그림1) 에러발생현황

발생한 에러


일단 구글링을 하기전 activitylog.xml을 한번 들여다보기로 했다


Activity Monitor Log


PkgDefManagement: PkgDef cache fast check returned false; cache will be regenerated. ..


긁어서 검색해봤지만 별 수확 없었음


어쩔수없이

activitylog.xml visual studio 2019 error 를 검색해보기로함


Please close all Visual Studio instances, and go to this directory C:\Users[user name]\AppData\Local\Microsoft\VisualStudio\16.0_XXXX then find and rename(or delete) every subfolders named “ComponentModelCache”.


밑에 댓글에 도움이 안됫다는 말이 있지만 한번 해보기로함


캐시삭제


그래도 안됨 ㅋ.



계속 안될때는 이렇게 해보라는 답변이 있었음

If this issue still persists, please kindly try following steps to troubleshoot.


Launch Developer Command Prompt for VS 2019 > type devenv /ResetSkipPkgs > press Enter to start VS.


Run Visual Studio 2019 as administrator.


Launch Visual Studio Installer > find Visual Studio 2019 > More/Update > Repair to repair or update VS 2019.


믿고 진행



관리자권한으로 업데이트 진행!


과연??!?!

응 안됨 ㅋ



내가 통한 해결법(Fixed!!!)

window->packageManager->Visual Studio Editor-> Remove!!

패키지에서 비쥬얼스튜디오에디터 삭제!!!



이제된다!!!!

Done!



git rejected error(feat. cherry-pick)

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