NUMA(Non-Uniform Memory Access)는 멀티 프로세서 환경에서 적용되는 메모리 접근 방식이다. NUMA에서 각 CPU는 로컬 메모리를 갖고 있어서 다른 CPU의 메모리에 접근 여부와 상관없이 자유롭게 메모리에 접근이 가능하다. 이것을 로컬 액세스(Local Access)라고 하며 로컬 메모리와 CPU를 합쳐서 하나의 노드(Node)라고 부른다. 하지만 로컬 메모리의 양이 모자라면 다른 CPU의 메모리에 접근이 필요할 때도 있는데 이 때 성능 저하가 일어나게 된다. 이것을 리모트 액세스 (Remove Access)라고 한다.
numactl
명령어로 NUMA와 관련된 정책을 확인하거나 설정할 수 있다.
$ numactl --show // 정책을 확인하는 옵션이다.
policy: default
preferred node: current
physcpubind: 0 1 2 3
cpubind: 0
nodebind: 0
membind: 0
NUMA와 관련된 메모리 할당 정책은 총 4가지이다.
$ numactl -H // 가용한 노드를 확인하는 옵션이다.
available: 1 nodes (0)
node 0 cpus: 0 1 2 3
node 0 size: 7631 MB
node 0 free: 7103 MB
node distances:
node 0
0: 10
위의 시스템에서는 노드가 하나뿐이지만 노드가 둘 이상인 시스템에서는 리모트 액세스시 어느정도의 시간이 소요되는지 확인할 수 있다.
numastat
명령어로는 시스템에 할당된 메모리의 상태를 확인할 수 있다.
$ numastat -cm
Per-node system memory usage (in MBs):
Node 0 Total
------ -----
MemTotal 7632 7632
MemFree 7104 7104
MemUsed 528 528
Active 172 172
Inactive 257 257
Active(anon) 33 33
Inactive(anon) 8 8
Active(file) 140 140
Inactive(file) 249 249
Unevictable 4 4
Mlocked 4 4
Dirty 0 0
Writeback 0 0
FilePages 400 400
Mapped 46 46
AnonPages 35 35
Shmem 9 9
KernelStack 3 3
PageTables 3 3
NFS_Unstable 0 0
Bounce 0 0
WritebackTmp 0 0
Slab 39 39
SReclaimable 22 22
SUnreclaim 17 17
AnonHugePages 12 12
HugePages_Total 0 0
HugePages_Free 0 0
HugePages_Surp 0 0
메모리 할당 정책에 따라 전체적인 메모리 가용량(free)는 많이 남았는데도 특정한 노드에서 swap 메모리를 사용하게 되어 성능이 저하되는 문제가 발생할 때가 있다. 그것을 확인하는데에서 numastat
명령어가 유용하다. 각 프로세스가 어떤 정책으로 메모리를 할당받고 있는지는 /proc/<pid>/numa_maps
파일을 통해 알 수 있다.
NUMA의 메모리 할당 정책을 적절하게 설정하면 시스템 성능을 최적화할 수 있다. 이는 필요로 하는 메모리의 크기와 스레드 방식에 가장 많은 영향을 받는다.