디시인사이드 갤러리

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

갤러리 본문 영역

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

ㅆㅇㅆ(124.216) 2025.02.09 21:57:11
조회 84 추천 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/02/10 - -
공지 프로그래밍 갤러리 이용 안내 [86] 운영자 20.09.28 41526 64
2817086 잠재적 독재자를 가려내는 4가지 주요 신호 발명도둑잡기갤로그로 이동합니다. 16:42 0 0
2817085 딱 한 잔만큼의 깊고 너른 다독임 발명도둑잡기갤로그로 이동합니다. 16:41 1 0
2817084 친중매국극좌 우원식의 실체 ♥멸공의냥덩♥갤로그로 이동합니다. 16:41 0 0
2817083 아이유 콘서트, 영화관 천장에 띄운 1천 개의 황홀한 드론 발명도둑잡기갤로그로 이동합니다. 16:39 0 0
2817082 돈벌이된 집회… 전광훈 측 ‘알뜰폰 판촉’ 논란 발명도둑잡기갤로그로 이동합니다. 16:38 0 0
2817081 반려동물 기생충이 사람에게 감염된다?… 절반 이상 몰랐다 발명도둑잡기갤로그로 이동합니다. 16:37 2 0
2817080 아~ 애널 ㄹㅇ 체딸되니까 짜증나네 머리가 안 돌아감 [1] ♥멸공의냥덩♥갤로그로 이동합니다. 16:06 18 0
2817079 아정당 3년약정 쉽지않음 [4] 멍청한유라ㅋ갤로그로 이동합니다. 16:01 30 0
2817078 나님 취미로 코딩하다 국비간 후기 [5] 프갤러(125.177) 15:58 50 0
2817077 보안 안가는이유 [1] ㅇㅇ(223.38) 15:54 22 0
2817076 화교분탕들의 대학축제 억까날조 - 야희롱 숏본 제작자 정체 ㅇㅇ(39.7) 15:46 19 0
2817075 애니메이션추천좀ㅇㅅㅇ [3] 익명의따당이갤로그로 이동합니다. 15:42 34 0
2817073 너무 기여워서 미안합니다 [8] AppHiki갤로그로 이동합니다. 15:40 32 0
2817072 다들 머리가 좋네 코딩 어렵구만 [1] ㅇㅇ(59.28) 15:38 28 0
2817071 보안 업계 오는 사람이 왜이리 적을까 [4] ㅇㅇ갤로그로 이동합니다. 15:31 38 0
2817070 오늘 작업은 리팩토링한거 더해서 근접 공격 부드럽게 수정해봐야겠다 ㅆㅇㅆ(124.216) 15:27 21 0
2817069 야 근데 디시 차단 시스템 있잖아 이거 알람도 안울리게 할수 없냐 [7] ㅆㅇㅆ(124.216) 15:18 39 0
2817068 나님 재활용 하러 왔다가. 넥도리아(223.38) 15:18 19 0
2817067 이번에 AI 대부 벤지오가 오픈 AI는 초지능 공유 안할거라고 말했네 ㅆㅇㅆ(124.216) 15:16 15 0
2817066 동남아 백수 오늘의 런치야. [4] 40대프린이(124.217) 15:08 36 0
2817065 인터넷 티비 원래 이렇게 비쌈? [6] 고고갤로그로 이동합니다. 14:52 31 0
2817064 어셈블리어 잘하는사람 있냐 [6] ㅇㅇ갤로그로 이동합니다. 14:47 46 0
2817063 리눅스 커널 관련해서 RUST 사용으로 말많나보네 ㅆㅇㅆ(124.216) 14:44 21 0
2817062 올해 유독 추위가 오래가는듯 ♥멸공의냥덩♥갤로그로 이동합니다. 14:41 17 0
2817061 프리랜서 뽑으려는데 둘 중 누구 픽? [4] 프갤러(211.235) 14:25 41 0
2817060 시발 윈도우에서 메이븐 빌드 개빡치네 [1] 프갤러(175.193) 14:17 34 0
2817059 지난 주 성과 프갤러(220.79) 14:10 22 0
2817058 확실히 체력 회복 안된상태에서는 효율이 존나 떨어짐 ♥멸공의냥덩♥갤로그로 이동합니다. 14:05 14 0
2817057 ❤✨☀⭐나님 시작합니당⭐☀✨❤ ♥멸공의냥덩♥갤로그로 이동합니다. 13:56 13 0
2817056 화교분탕들의 대학축제 억까날조 - 야희롱 논란 ㅇㅇ(175.223) 13:51 17 0
2817055 주말에 에너지를 넘 많이 써서 그런지.. ♥멸공의냥덩♥갤로그로 이동합니다. 13:51 16 0
2817054 판세 현황 ♥멸공의냥덩♥갤로그로 이동합니다. 13:40 20 0
2817053 누가 빨리 다른 떡밥좀 굴려줘 [3] 딱님갤로그로 이동합니다. 13:27 38 1
2817052 전공자면 걍 소마 가면되냐? 프갤러(172.225) 13:10 29 0
2817051 쉬는시간이라서 읽어봤는데 딱국 이 병신새끼 [2] hrin(118.235) 13:08 42 2
2817050 맥미니 m4 깡통 백엔드 개발 ㄱㅊ? [1] 프갤러(211.36) 12:34 36 0
2817049 ❤✨☀⭐나님 시작합니당⭐☀✨❤ ♥멸공의냥덩♥갤로그로 이동합니다. 12:29 13 0
2817048 이직 준비중 ㅇㅇ 질문 받는다 [9] 섹카냥갤로그로 이동합니다. 12:04 76 0
2817047 이제 경력 5년을 향해가는데,, 요즘 연봉 다 높네? 프갤러(211.36) 11:59 40 0
2817046 젊었을 때 대시 안한 여자 생각하면 눈물이 난다 [1] 발명도둑잡기갤로그로 이동합니다. 11:41 32 0
2817045 학부모의 자녀들은 [1] 발명도둑잡기갤로그로 이동합니다. 11:36 21 0
2817044 오늘 5시간 잤더니 꽤 피곤하다 발명도둑잡기갤로그로 이동합니다. 11:29 22 0
2817043 [전문] 이재명 "'내 삶 변하지 않았다' 질책 수용...국민소환제 발명도둑잡기갤로그로 이동합니다. 11:26 17 1
2817042 아스카의 전화위복을 기원해주세요 [10] 아스카영원히사랑해갤로그로 이동합니다. 11:17 80 2
2817041 프랑스 15구역에 한국인이 모여사는 발명도둑잡기갤로그로 이동합니다. 11:17 25 0
2817040 화교분탕들의 대학축제 억까날조 - 썰린 념글 ㅇㅇ(39.7) 11:09 26 0
2817039 ㅎㅇ ㅇㅇ(119.56) 11:04 23 0
2817038 하드웨어 관련해서 윈도우 프로그래밍 하는건 프갤러(211.195) 10:42 34 0
2817037 K.N.King. C Programming: A Modern Approa 골고루헬스갤로그로 이동합니다. 10:41 23 0
뉴스 '한국의 셀린디온' 서제이, 11일 깊은 감성 녹인 싱글 '마지막인 것처럼' 발표 디시트렌드 10:00
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2