如何在C语言中将已分配数组迁移至指定NUMA节点?
迁移已分配内存到指定NUMA节点的实现方法
可以通过NUMA库提供的函数实现已有内存的迁移,以下是两种常用方案:
方案一:使用numa_move_pages()直接迁移页
numa_move_pages()是专门用于将指定内存页迁移到目标NUMA节点的接口,能精确控制每个页的迁移目标。
示例代码:
#include <numa.h> #include <numaif.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main() { // 原内存分配 void *mem = mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); if (mem == MAP_FAILED) { perror("mmap failed"); exit(EXIT_FAILURE); } // 初始化内存(模拟业务场景) memset(mem, 0xAA, 8192); const int target_node = 0; // 指定目标NUMA节点 const int page_count = 2; // 8192字节对应2个4KB标准页 void *pages[page_count] = {mem, mem + 4096}; // 每个页的起始地址 int target_nodes[page_count] = {target_node, target_node}; // 每个页的目标节点 int migrate_status[page_count]; // 存储每个页的迁移结果 // 执行迁移:MPOL_MF_MOVE 强制迁移已驻留的页 int ret = numa_move_pages(0, page_count, pages, target_nodes, migrate_status, MPOL_MF_MOVE); if (ret != 0) { perror("numa_move_pages failed"); // 排查每个页的迁移失败原因 for (int i = 0; i < page_count; i++) { if (migrate_status[i] != 0) { printf("Page %d migration failed, status: %d\n", i, migrate_status[i]); } } munmap(mem, 8192); exit(EXIT_FAILURE); } // 验证迁移结果:查询当前内存所在节点 int current_node; ret = numa_move_pages(0, page_count, pages, NULL, ¤t_node, MPOL_MF_QUERY); if (ret == 0) { printf("Memory successfully migrated to NUMA node %d\nCurrent node verification: %d\n", target_node, current_node); } munmap(mem, 8192); return EXIT_SUCCESS; }
方案二:使用mbind()绑定并迁移内存
mbind()可设置内存的NUMA策略,配合MBIND_MIGRATE标志,能将已有内存页迁移到指定节点并绑定后续分配的页。
示例代码:
#include <numa.h> #include <sys/mman.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main() { void *mem = mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); if (mem == MAP_FAILED) { perror("mmap failed"); exit(EXIT_FAILURE); } memset(mem, 0xAA, 8192); const int target_node = 0; // 创建节点掩码,指定目标NUMA节点 numa_bitmask *nodemask = numa_bitmask_alloc(numa_max_node() + 1); numa_bitmask_setbit(nodemask, target_node); // 绑定内存到目标节点并迁移已有页:MPOL_BIND 绑定策略,MBIND_MIGRATE 触发迁移 int ret = mbind(mem, 8192, MPOL_BIND, nodemask->maskp, nodemask->size, MBIND_MIGRATE); if (ret != 0) { perror("mbind failed"); numa_bitmask_free(nodemask); munmap(mem, 8192); exit(EXIT_FAILURE); } printf("Memory bound and migrated to NUMA node %d successfully\n", target_node); numa_bitmask_free(nodemask); munmap(mem, 8192); return EXIT_SUCCESS; }
注意事项
- 编译时需链接NUMA库,添加编译参数
-lnuma,例如:gcc -o migrate_demo migrate_demo.c -lnuma - 确保系统支持NUMA架构,可通过
numactl --hardware命令查看节点信息 - 内存需已驻留(示例中使用
MAP_POPULATE预分配页,若未设置需先触发页错误让页加载到内存)
内容的提问来源于stack exchange,提问作者Mohammad Siavashi
相关产品推荐
相关产品推荐

