You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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, &current_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 15:18:13