NUMA (Non-Uniform Memory Access) 아키텍처

1. UMA vs NUMA

UMA (Uniform Memory Access)

  • 모든 CPU가 하나의 공유 메모리에 동일한 접근 시간으로 접근하는 구조
  • 구조가 단순하고 프로그래밍이 쉬움
  • CPU 수가 늘어나면 메모리 버스에 병목 발생
  • 소규모 시스템(데스크탑, 노트북, Raspberry Pi 등)에서 사용

NUMA (Non-Uniform Memory Access)

  • 각 CPU(또는 CPU 그룹)가 자기만의 로컬 메모리를 보유
  • 다른 CPU의 메모리에도 접근 가능하지만, 인터커넥트를 경유하므로 시간이 더 걸림
  • 대규모 멀티소켓 서버에서 확장성을 확보하기 위해 사용

접근 구조 비교

UMA:   CPU → 공유 버스 → 메모리 (모든 CPU가 동일 지연시간)
NUMA:  CPU₁ → 로컬 메모리₁ (빠름) / CPU₁ → 원격 메모리₂ (느림, 인터커넥트 경유)

2. NUMA 노드란?

  • CPU(또는 CPU 그룹) + 해당 CPU에 직접 연결된 로컬 메모리를 하나의 단위로 묶은 것
  • 보통 물리 CPU 소켓 1개 = NUMA 노드 1개
  • 단, AMD EPYC 같은 칩렛 구조에서는 하나의 소켓 안에서도 여러 NUMA 노드가 생길 수 있음
  • 노드의 기준은 메모리 컨트롤러와 CPU 코어 간의 물리적 접근 거리

3. CPU 소켓 / 코어 / 스레드 계층 구조

계층 의미 lscpu 항목

소켓 (Socket)메인보드에 CPU를 꽂는 물리적 자리. 소켓 1개 = 물리 CPU 1개Socket(s)
코어 (Core)하나의 물리 CPU 안에 있는 독립적인 연산 유닛Core(s) per socket
스레드 (Thread)하이퍼스레딩 지원 시 코어 하나가 논리적으로 2개로 동작Thread(s) per core

예: 2소켓, 소켓당 16코어, 하이퍼스레딩 지원 → 물리 CPU 2개, 코어 32개, 논리 프로세서 64개


4. NUMA 메모리 할당 정책

Local Allocation (기본 정책)

  • 프로세스가 실행 중인 CPU의 로컬 노드에서 메모리 할당
  • 별도 설정 없으면 기본값
  • 지연시간이 가장 짧아 대부분의 경우 최적

Bind

  • 지정한 특정 노드에서만 메모리 할당
  • 해당 노드 메모리 부족 시 다른 노드로 넘어가지 않고 OOM 발생 가능
  • 메모리 위치를 확실히 고정해야 할 때 사용
numactl --membind=0 ./my_app    # 노드 0에서만 메모리 할당

Interleave

  • 여러 노드에 라운드 로빈 방식으로 페이지를 번갈아 할당
  • 특정 노드에 부하가 몰리는 것을 방지
  • 메모리 대역폭을 고르게 활용
  • 접근 패턴이 불규칙한 공유 데이터(대규모 해시 테이블, DB 버퍼 풀 등)에 유리
numactl --interleave=all ./my_app    # 모든 노드에 균등 분산

Preferred

  • 지정한 노드에서 우선 할당, 여유 없으면 다른 노드에서 할당
  • Bind와 달리 OOM 위험 없이 선호도만 표현하는 유연한 정책
numactl --preferred=1 ./my_app    # 노드 1 우선, 부족하면 다른 노드

정책 선택 기준

상황 추천 정책

대부분의 일반적인 경우Local (기본값)
지연시간에 민감한 실시간 워크로드Bind
대역폭이 중요하거나 접근 패턴이 불규칙Interleave
약간의 선호도만 주고 싶을 때Preferred

5. NUMA 모니터링: numastat

주요 항목

항목 의미

numa_hit의도한 노드에서 메모리 할당 성공한 횟수
numa_miss의도한 노드에 메모리 부족으로 다른 노드에서 할당된 횟수
numa_foreign다른 노드가 이 노드에서 메모리를 가져간 횟수 (numa_miss의 반대편 관점)
interleave_hitInterleave 정책으로 할당된 페이지 중 로컬 노드에 떨어진 횟수
local_node프로세스가 실행 중인 CPU의 로컬 노드에서 할당된 횟수
other_node원격 노드에서 할당된 횟수

단일 노드 시스템 예시 (WSL 환경)

                           node0
numa_hit                14946472
numa_miss                      0
numa_foreign                   0
interleave_hit              1298
local_node              14946472
other_node                     0
  • 노드가 1개뿐이므로 miss, foreign, other_node가 모두 0
  • interleave_hit이 소량 존재하는 이유: 커널이 부팅 초기에 일부 자료구조를 interleave로 할당하기 때문

numastat이 free보다 유용한 경우

  • free는 시스템 전체 메모리 총량만 표시
  • numastat은 노드별 메모리 사용량을 분리 표시
  • 전체적으로 메모리 여유가 있어도, 특정 노드에 메모리가 몰려 해당 노드에서 swap이 발생하는 상황을 numastat으로 감지 가능
  • numastat -m: 노드별 메모리 사용량을 MB 단위로 확인
  • numastat -p <PID>: 특정 프로세스의 NUMA 메모리 분포 확인

6. 리눅스 커널과 NUMA

  • 리눅스 커널은 NUMA를 항상 지원하지만, 실제로 의미 있게 동작하는지는 하드웨어에 달려있음
  • 커널 부팅 시 ACPI의 SRAT 테이블 등에서 NUMA 토폴로지 정보를 읽음
  • numactl --hardware로 NUMA 토폴로지 확인 가능

NUMA가 실질적으로 동작하는 경우

  • 멀티소켓 서버 (Intel Xeon 2소켓 이상, AMD EPYC 등)
  • 일부 데스크탑 CPU (AMD Threadripper 등 칩렛 구조에서 노드가 여러 개로 잡히는 경우)

커널은 지원하지만 단일 노드(=UMA)로 동작하는 경우

  • 일반 데스크탑/노트북 (Intel Core, AMD Ryzen)
  • SBC (Raspberry Pi)
  • WSL 환경

Read more

mybloodyvalentine 3집 loveless

마이블러디발렌타인의 정규 2집 loveless 엘피를 김밥레코즈에서 5만원가량의 금액으로 구매. 요건 평생 들어도 질리지않을거같아 바이닐로 구매했다. 물리적인 이슈가 발생하지않는 한 이제 스트리밍 플랫폼의 의존성없이 평생 청취 가능하다 내부 크레딧 개인적으로 빌린다 부처의 맥아리없는 보컬을 참 좋아한다. 바이닐 커버를 벗기면 평범하다 0:00 /0:12 1× 2집 loveless만큼 3집 mbv도 좋아해서 아마

By 권동혁