NUMA 환경 이해와 성능 최적화 가이드

NUMA(Non-Uniform Memory Access)는 현대 서버 아키텍처에서 흔히 볼 수 있는 메모리 구성 방식입니다. NUMA 환경에서는 CPU 코어가 메모리에 접근하는 속도가 코어가 속한 노드(Node)의 메모리에 접근할 때와 다른 노드의 메모리에 접근할 때 달라집니다. 이러한 차이를 이해하지 못하고 애플리케이션을 실행하면 성능 저하가 발생할 수 있습니다. 이 글에서는 NUMA 환경의 기본 개념부터 시작하여 성능 분석, 튜닝 방법, 그리고 흔한 오해까지 상세하게 다룹니다.

NUMA란 무엇인가?

NUMA는 여러 개의 CPU 코어와 메모리 모듈이 연결된 시스템 아키텍처입니다. 각 CPU 코어는 로컬 메모리(Local Memory)라고 불리는 자체 메모리 모듈을 가지고 있습니다. CPU 코어가 로컬 메모리에 접근할 때는 속도가 빠르지만, 다른 노드의 메모리에 접근할 때는 네트워크를 거쳐야 하므로 지연 시간이 발생합니다. 이러한 지연 시간 차이를 NUMA penalty라고 합니다.

NUMA 아키텍처는 대규모 멀티 프로세서 시스템에서 메모리 대역폭 병목 현상을 해결하기 위해 등장했습니다. 여러 개의 독립적인 노드를 구성함으로써 각 노드는 자체 메모리 대역폭을 활용할 수 있게 됩니다. 하지만 NUMA penalty 때문에 애플리케이션을 NUMA 환경에 최적화하는 것이 중요합니다.

NUMA 환경이 왜 중요할까요?

NUMA 환경 식별 방법

NUMA 시스템인지 확인하는 방법은 운영체제별로 다릅니다.

Linux

Linux에서는 `numactl` 명령어를 사용하여 NUMA 정보를 확인할 수 있습니다.

numactl --hardware

이 명령어는 시스템의 NUMA 노드 수, 각 노드에 할당된 CPU 코어, 메모리 용량 등을 보여줍니다. `lscpu` 명령어를 통해서도 NUMA node 정보를 확인할 수 있습니다.

lscpu

Windows

Windows에서는 작업 관리자(Task Manager)의 성능 탭에서 CPU 정보를 확인하거나, 시스템 정보(System Information) 도구를 사용하여 NUMA 지원 여부를 확인할 수 있습니다. 또한 PowerShell 명령어를 사용할 수도 있습니다.

Get-WmiObject Win32_ComputerSystem | Select-Object HypervisorPresent

HypervisorPresent 값이 True이면 가상화 환경이고, False이면 물리 시스템입니다. 물리 시스템의 경우, CPU 정보에서 NUMA 노드 정보를 확인할 수 있습니다.

NUMA 환경에서의 성능 분석

NUMA 환경에서 성능 문제를 진단하려면 메모리 접근 패턴을 분석해야 합니다. 다음은 성능 분석에 도움이 되는 도구와 방법입니다.

성능 분석 시 다음 사항에 주목해야 합니다.

NUMA 튜닝 방법

NUMA 환경에서 성능을 최적화하는 방법은 다양합니다. 다음은 몇 가지 주요 튜닝 방법입니다.

1. 프로세스/스레드 NUMA 바인딩

프로세스 또는 스레드를 특정 NUMA 노드에 바인딩하면 해당 노드의 로컬 메모리를 우선적으로 사용하도록 할 수 있습니다. 이를 통해 remote memory access를 줄여 성능을 향상시킬 수 있습니다.

Linux:

numactl --cpunodebind=0 --membind=0 ./my_application

이 명령어는 `my_application`을 NUMA 노드 0에 바인딩합니다.

Windows:

SetProcessAffinityMask 함수 또는 SetThreadAffinityMask 함수를 사용하여 프로세스 또는 스레드의 선호도 마스크를 설정할 수 있습니다.

2. 메모리 할당 정책

메모리 할당 정책을 조정하여 메모리가 특정 NUMA 노드에 할당되도록 할 수 있습니다. 예를 들어, first-touch 정책을 사용하면 메모리에 처음 접근하는 CPU 코어가 속한 노드에 메모리가 할당됩니다.

Linux:

numactl --preferred=0 ./my_application

이 명령어는 `my_application`이 메모리를 할당할 때 NUMA 노드 0을 우선적으로 사용하도록 합니다.

3. Huge Page 사용

Huge Page는 기본 페이지 크기보다 큰 메모리 페이지를 사용하는 기술입니다. Huge Page를 사용하면 TLB(Translation Lookaside Buffer) 미스율을 줄여 메모리 접근 성능을 향상시킬 수 있습니다. NUMA 환경에서는 Huge Page를 특정 노드에 할당하여 성능을 더욱 최적화할 수 있습니다.

Linux:

`/etc/sysctl.conf` 파일에 Huge Page 관련 설정을 추가하고 시스템을 재시작하거나 `sysctl -p` 명령어를 실행하여 설정을 적용합니다.

vm.nr_hugepages=1024

애플리케이션에서 Huge Page를 사용하려면 `mmap` 함수를 사용하여 Huge Page를 요청해야 합니다.

4. 데이터 구조 최적화

데이터 구조를 설계할 때 NUMA 아키텍처를 고려해야 합니다. 예를 들어, 데이터 구조를 여러 NUMA 노드에 분산하여 저장하고, 각 노드의 CPU 코어가 해당 노드의 로컬 데이터에 접근하도록 하면 성능을 향상시킬 수 있습니다.

5. 라이브러리 활용

NUMA를 지원하는 라이브러리를 사용하면 애플리케이션 개발자가 직접 NUMA 관련 코드를 작성하지 않아도 NUMA 최적화를 수행할 수 있습니다. 예를 들어, Intel Threading Building Blocks (TBB)는 NUMA 인식 스케줄러를 제공하여 스레드를 NUMA 노드에 효율적으로 분배할 수 있습니다.

NUMA 환경에서의 흔한 오해

NUMA 최적화 시 고려 사항

NUMA 환경에서 비용 효율적인 활용 방법

자주 묻는 질문과 답변

Q: NUMA 바인딩을 하면 어떤 효과가 있나요?
A: NUMA 바인딩은 프로세스 또는 스레드가 특정 NUMA 노드의 로컬 메모리를 우선적으로 사용하도록 하여 remote memory access를 줄이고 성능을 향상시키는 효과가 있습니다.
Q: Huge Page는 어떻게 활성화하나요?
A: Linux에서는 `/etc/sysctl.conf` 파일에 Huge Page 관련 설정을 추가하고 시스템을 재시작하거나 `sysctl -p` 명령어를 실행하여 설정을 적용합니다. 애플리케이션에서는 `mmap` 함수를 사용하여 Huge Page를 요청해야 합니다.
Q: NUMA 환경에서 성능 문제가 발생하면 어떻게 진단해야 하나요?
A: `perf`, `VTune Amplifier`, `Windows Performance Analyzer` 등 성능 분석 도구를 사용하여 CPU 사이클, 캐시 미스, 메모리 접근 시간 등 다양한 성능 지표를 측정하고 분석하여 병목 현상을 파악해야 합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다