一、什麼是NUMA
NUMA的全稱是Non-Uniform Memory Access,中文翻譯為非一致性內存訪問,是一種在多處理器系統中使用的內存架構和訪問優化技術。
在NUMA架構下,多個處理器可以共享一部分內存,但是訪問不同的內存區域的時間不同,這就是“非一致性”的含義。為了優化訪問性能,Linux系統對NUMA架構提供了一些支持和優化手段。
/*
* 查看當前系統是否支持NUMA
*/
# cat /proc/cpuinfo | grep -i numa
二、為什麼要使用NUMA
在單處理器系統中,所有內存都是一致的,處理器可以隨意訪問任何內存位置,不需要花費額外的時間。但是在多處理器系統中,不同處理器訪問距離較遠的內存位置的時間會變得很長,這就導致了可觀的性能下降。
NUMA架構通過將內存分成多個節點來優化內存訪問性能。每個節點擁有自己的內存,同時還能夠訪問其他節點的內存。這樣,處理器只需要訪問與自己所在節點相鄰的內存節點,可以有效減少訪問時間。
三、如何使用NUMA
1. 綁定進程
在NUMA架構下,Linux系統提供了一個針對進程的優化手段:CPU和內存綁定。通過指定進程運行的CPU和內存節點,可以提高進程的性能。
/*
* 綁定當前進程到CPU 0 和 NUMA節點 0
*/
# numactl --cpubind=0 --membind=0 <command>
2. NUMA感知分配
NUMA感知分配是一種對內存分配進行優化的手段。在NUMA感知分配中,內存會被分配到最適合它的節點上,而不是默認的全局節點。
/*
* 為指定進程分配一塊大小為2GB的內存,並將其分配到NUMA節點1上
*/
# numactl --membind=1 <command>
# ptr = numa_alloc_onnode(2<<30, 1); // 用於內存分配的C函數
3. NUMA感知調度
NUMA感知調度是一種優化調度用於NUMA架構的進程的手段。在NUMA感知調度中,系統會盡量將進程調度到與它綁定的CPU和內存節點相同的CPU上。
/*
* 設置NUMA感知調度
*/
# echo 1 > /proc/sys/kernel/numa_balancing
# echo 1 > /proc/sys/kernel/sched_numa_placement
四、NUMA帶來的性能提升舉例
下面是在NUMA架構下啟用NUMA感知分配和調度的例子。在這個例子中,通過在多個NUMA節點上啟用線程,從而使用了多個處理器和多個內存節點,大大提高了程序的性能。
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <numa.h>
#define THREAD_NUM 4
#define MEM_SIZE (1<<30)
void* thread_func(void* arg) {
int node_id = *(int*)arg;
char* mem;
mem = (char*)numa_alloc_onnode(MEM_SIZE, node_id);
for(long i = 0; i < MEM_SIZE; i++)
mem[i] = 1;
}
int main() {
int node_num = numa_max_node() + 1;
pthread_t tids[THREAD_NUM];
for(int i = 0; i < THREAD_NUM; i++) {
pthread_create(&tids[i], NULL, thread_func, (void*)&(i % node_num));
}
for(int i = 0; i < THREAD_NUM; i++)
pthread_join(tids[i], NULL);
return 0;
}
五、總結
NUMA是一種優化多處理器系統中內存訪問性能的架構和技術。在Linux系統中,我們可以使用CPU和內存綁定、NUMA感知分配和調度等手段來進行性能優化。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/237742.html