디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

내가 디자인한 NUMA 오브젝트 노드풀

ㅆㅇㅆ(124.216) 2025.02.09 21:57:11
조회 156 추천 0 댓글 8


using System;

using System.Runtime.CompilerServices;

using System.Threading;


namespace JDWTaskSystem

{

    /// <summary>

    /// SchedulerNode는 스케줄러에서 사용되는 작업 단위를 나타냄

    /// (예: 작업(Action)과 작업 소스(Source)를 포함)

    /// </summary>

    public class SchedulerNode

    {

        public ITaskCompletionAction Action;

        public ITaskSource Source;


        [MethodImpl(MethodImplOptions.AggressiveInlining)]

        public void Reset()

        {

            Action = null;

            Source = null;

        }

    }


    /// <summary>

    /// NUMA(Non-Uniform Memory Access) 최적화 기반 락-프리(Lock-Free) 클래스 풀

    /// SchedulerNode 객체를 미리 할당된 배열에서 관리하여 메모리 할당을 최소화하고 성능을 향상시킴

    /// NUMA 노드에 따라 객체를 분산하여 메모리 접근 병목을 줄임

    /// </summary>

    public class SchedulerNodePool

    {

        private SchedulerNode[][] pools;       // NUMA 노드별 객체 풀 (2차원 배열)

        private int[] poolIndices;             // 각 NUMA 노드에서 현재 사용 가능한 객체의 인덱스

        private int numaNodes;                 // NUMA 노드 개수

        private int poolSize;                  // 풀의 초기 크기


        [ThreadStatic]

        private static bool isNumaInitialized;

        [ThreadStatic]

        private static int threadNumaNode;


        /// <summary>

        /// NUMA 기반 클래스 풀을 생성함

        /// </summary>

        /// <param name="numaNodes">

        /// NUMA 노드 개수 (보통 CPU 코어 수의 절반 정도로 설정)

        /// </param>

        /// <param name="poolSize">풀의 초기 크기</param>

        public SchedulerNodePool(int numaNodes, int poolSize)

        {

            this.numaNodes = numaNodes;

            this.poolSize = poolSize;

            pools = new SchedulerNode[numaNodes][];

            poolIndices = new int[numaNodes];


            for (int i = 0; i < numaNodes; i++)

            {

                pools[i] = new SchedulerNode[poolSize];

                poolIndices[i] = -1; // 초기에는 아무 객체도 대여되지 않음 (-1)

            }

            isNumaInitialized = false;

            threadNumaNode = 0;

        }


        /// <summary>

        /// 현재 NUMA 노드에서 SchedulerNode 객체를 대여함

        /// 락-프리 방식으로 작동하여 성능을 최적화함

        /// </summary>

        /// <returns>대여된 SchedulerNode 객체</returns>

        [MethodImpl(MethodImplOptions.AggressiveInlining)]

        public SchedulerNode Rent()

        {

            int numaNode = GetNumaNode();

            int index = Interlocked.Increment(ref poolIndices[numaNode]);


            // 풀의 크기를 초과하면 풀 확장 (동기화 필요)

            if (index >= poolSize)

            {

                ResizePool(numaNode, poolSize * 2);

                index = 0;

            }


            SchedulerNode obj = pools[numaNode][index];

            pools[numaNode][index] = null;

            return obj ?? new SchedulerNode();

        }


        /// <summary>

        /// 사용한 SchedulerNode 객체를 다시 풀에 반환하여 재사용할 수 있도록 함

        /// </summary>

        /// <param name="item">반환할 SchedulerNode 객체</param>

        [MethodImpl(MethodImplOptions.AggressiveInlining)]

        public void Return(SchedulerNode item)

        {

            item.Reset();

            int numaNode = GetNumaNode();

            int index = Interlocked.Decrement(ref poolIndices[numaNode]);


            if (index >= 0)

            {

                pools[numaNode][index] = item;

            }

        }


        /// <summary>

        /// 특정 NUMA 노드의 풀 크기를 확장함

        /// 배열을 새 크기로 복사하여 공간을 확보함

        /// </summary>

        /// <param name="numaNode">확장할 NUMA 노드</param>

        /// <param name="newSize">새로운 풀 크기</param>

        private void ResizePool(int numaNode, int newSize)

        {

            lock (pools)

            {

                if (newSize <= poolSize) return;


                SchedulerNode[] newPool = new SchedulerNode[newSize];

                Array.Copy(pools[numaNode], newPool, poolSize);

                pools[numaNode] = newPool;

                poolSize = newSize;

            }

        }


        /// <summary>

        /// 현재 실행 중인 스레드의 NUMA 노드를 결정함

        /// ThreadStatic 변수를 사용하여 NUMA 노드를 캐싱함

        /// </summary>

        /// <returns>현재 스레드의 NUMA 노드 인덱스</returns>

        [MethodImpl(MethodImplOptions.AggressiveInlining)]

        private int GetNumaNode()

        {

            if (!isNumaInitialized)

            {

                threadNumaNode = Thread.CurrentThread.ManagedThreadId % numaNodes;

                isNumaInitialized = true;

            }

            return threadNumaNode;

        }


        /// <summary>

        /// 현재 풀의 크기를 반환함

        /// </summary>

        /// <returns>풀 크기</returns>

        public int GetPoolSize()

        {

            return poolSize;

        }

    }

}



사실 NUMA 노드를 직접적으로 가져오는 GetNumaProcessorNode() API를 쓴다거나 해야하지만

나는 게임을 만드는 이상 리눅스도 고려해서 써야하는데, 개념적으로 가져오는 방식으로 설계함




추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 실제 모습일지 궁금한 미담 제조기 스타는? 운영자 25/05/05 - -
공지 갤러리 댓글 기능 개선(멘션 기능) 안내 운영자 25/05/08 - -
공지 프로그래밍 갤러리 이용 안내 [88] 운영자 20.09.28 43851 65
2852939 자격증보다 실무랑 대외활동이중요함 ㅇㅇ(211.107) 03:57 7 0
2852938 인생은 기회의연속이다 , 내친구도 ㅇㅇ(39.7) 03:51 11 0
2852937 개발자도 정년보장안돼? [1] ㅇㅇ(58.126) 03:36 12 0
2852926 디씨 와이파이 차단되서 데이터 10기가 쓰고 두려움에 떠는 중 발명도둑잡기(39.7) 01:59 11 0
2852924 Maui가 좀 이상함 skglview랑 충돌자꾸 [1] ㅆㅇㅆ찡갤로그로 이동합니다. 01:56 15 0
2852923 이 젠폰4는 묻어두어야 할 것 같다. 아쉽다. 넥도리아(175.196) 01:56 18 0
2852922 사흘째 버튼 쉐이딩 적용 못하는중 ㅆㅇㅆ찡갤로그로 이동합니다. 01:55 11 0
2852919 이재명이 답이다 프갤러(106.102) 01:43 16 0
2852918 웃어라 ㅋㅋ 즐겁구나 음하하하하하하 ㅇㅇ(223.38) 01:43 14 0
2852917 해커톤 상금 들왔당 ㅇㅅㅇ [2] 익명의따당이갤로그로 이동합니다. 01:42 66 1
2852916 뭐야 직방보다 네이버 부동산이 더 매물 찾기 쉽네 ㅇㅇ(210.100) 01:37 13 0
2852912 통속의뇌 ㅇㅈㄹ하는 새끼는 운동을 안해본거임 ㅇㅅㅇ... ㅇㅇ(223.38) 01:23 16 0
2852910 그래 내가 잘 해야지 남이 잘 하는거 말해봐야 영혼추수갤로그로 이동합니다. 01:17 18 0
2852909 찢 범죄자라 싫다<-이해함 ㅆㅇㅆ(124.216) 00:52 17 0
2852907 내가 이재명을 응원하는 이유 [1] hrin(220.120) 00:41 35 0
2852906 연돈 hrin(220.120) 00:39 17 0
2852905 퇴근했다. 다시 작업시작한다 ㅆㅇㅆ(124.216) 00:30 22 0
2852904 나님 겨울잠에 들어갑니당❤+ ♥[휴먼계정]냥덩이♥갤로그로 이동합니다. 00:15 25 0
2852902 사카에 거닐다 호객 5번 당함 [2] 아스카영원히사랑해갤로그로 이동합니다. 05.08 35 0
2852901 나 도배기는 성공해서 돌려봄. 근데 주작은 [2] ㅆㅇㅆ찡갤로그로 이동합니다. 05.08 48 0
2852900 솔직히 히틀러처럼 다 도살하는거 말고 RyuDOG갤로그로 이동합니다. 05.08 46 0
2852899 님들 신입 연봉 3300이라는데 진짜인가여 [4] PyTorch갤로그로 이동합니다. 05.08 84 0
2852898 좌파는 정신병이당 ♥냥덩이♥갤로그로 이동합니다. 05.08 24 1
2852897 ㅆㅇㅆ 도 허수였네 [1] ㅇㅇ(211.235) 05.08 37 0
2852896 지피티 이새끼 뭐임? 내 코드를 읽고 있는데 말이 됨? [1] 프갤러(180.231) 05.08 42 0
2852894 빅뱅리턴즈 갤러리 코드걸렸는데 도배기 돌아가네 ㅇㅇ(211.235) 05.08 24 0
2852893 삘리삔의 저녁은 아름답다 ㅇㅅㅇ [5] 강유현갤로그로 이동합니다. 05.08 48 0
2852892 운동하다보면 먹는양도 점점 늘어나나요?? 먹으려고 노력하면?? [1] ㅇㅇ(223.38) 05.08 19 0
2852890 유현씨 좆밥인줄 알았는데 거리감 느껴졌음.. [4] ㅇㅇ(211.235) 05.08 77 0
2852887 이번에 스크트 털린거 [10] 류도그담당(114.202) 05.08 118 0
2852885 올해목표 [3] 프갤로갤로그로 이동합니다. 05.08 37 0
2852884 유현아 오히려 한곳에 때려박으면 지피티가 처리잘함 [1] ㅆㅇㅆ찡갤로그로 이동합니다. 05.08 40 0
2852883 생명공학과도 어떻게 보면 의료쪽이라고 볼수도 있나? 프갤러(121.175) 05.08 14 0
2852882 MVVM으로 구조 짜둔거 걍 뷰에 다 때려박기 시작 ㅇㅅㅇ [6] 강유현갤로그로 이동합니다. 05.08 50 0
2852876 코드 망치는 최강의 툴이 우리 눈앞에 있었네 ㅇㅅㅇ 강유현갤로그로 이동합니다. 05.08 45 0
2852872 프리랜서들 pypi 에 메인로직 넣으면 돈 떼일 걱정 없는거 아님? [1] ㅇㅇ(61.97) 05.08 46 0
2852870 나는 아름다운 코딩 추구하기에 난독화 안함 ㅆㅇㅆ찡갤로그로 이동합니다. 05.08 26 0
2852868 생명+통계학 복수전공은 너무 빡셀까? 프갤러(121.175) 05.08 21 0
2852863 생각 있는 전라도 사람이라면 전라도애서 도망쳐야 하는 EU ♥냥덩이♥갤로그로 이동합니다. 05.08 25 0
2852860 코드 난독화는 잘 하는 개발자의 필수 소양임 ㅇㅇ(211.235) 05.08 34 0
2852855 컴공쪽이 취업어렵다는게 아니지? [4] ㅇㅇ(118.235) 05.08 112 0
2852853 코드 난독화 말고 존나 더렵혀주는 익스텐션 없나 ㅇㅅㅇ [11] 강유현갤로그로 이동합니다. 05.08 94 0
2852850 안드로메다 급 응모결과가 발표된다. 넥도리아(175.196) 05.08 30 0
2852849 인생이 재미가 없어서 고통을 찾아다니는 중이다 ㅇㅇ... ㅇㅇ(223.38) 05.08 21 0
2852847 C++ 취업 되면 갈거냐? 프갤러(59.16) 05.08 39 0
2852846 시원시원한 인생을 살고싶은데 어찌 해야하냐... ㅇㅇ(223.38) 05.08 21 0
2852845 나 백엔드를 이번기회에 첨부터 구현해볼려고 [4] ㅆㅇㅆ찡갤로그로 이동합니다. 05.08 48 0
2852844 흠. 매일 운동하고 매일 공부하고 술도 잘마시는데 못사는 놈 봤음?? ㅇㅇ(223.38) 05.08 25 0
2852843 요즘 의식적으로 면치기 안 하고 있음 ㅇㅇ(211.235) 05.08 25 0
뉴스 제니, 가슴 비치는 시스루 입고 호텔방서 뽐낸 고혹미 디시트렌드 05.08
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2