首页 > 解决方案 > numaif.h:MPOL_LOCAL 未声明用于 mbind

问题描述

根据mbind man page,一种可能modeMPOL_LOCAL,它将内存区域放置在触发分配的 CPU 的同一节点中:

#include <numaif.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>    

#define N 134217728

int main() {
    uint64_t *a = (uint64_t*) malloc(N*sizeof(uint64_t));
    mbind(a, N, MPOL_LOCAL, 0, 0, MPOL_MF_STRICT | MPOL_MF_MOVE);
    printf("Hello world!\n");
    return 0;
}

但是,符号根本没有定义。

$ gcc-8 -lnuma example.c
example.c: In function ‘main’:
example.c:10:14: error: ‘MPOL_LOCAL’ undeclared (first use in this function); did you mean ‘MPOL_MAX’?
  mbind(a, N, MPOL_LOCAL, 0, 0, MPOL_MF_STRICT | MPOL_MF_MOVE);
              ^~~~~~~~~~
              MPOL_MAX
example.c:10:14: note: each undeclared identifier is reported only once for each function it appears in

更改为 egMPOL_INTERLEAVE使其编译和显示Hello world!就好了。

这里发生了什么?在这个阶段,我 100% 感到困惑。

我试过gcc/ g++4.9.2、5 和 8;在运行内核的三台不同的机器中4.17.12+(不知道它来自哪里),4.18.10(我自己编译)和4.15.0(包含在最新的 Linux Mint 中)。libnuma-dev已是最新。

标签: clinux-kernelnumadebian-basednumactl

解决方案


MPOL_LOCAL 在uapi/linux/mempolicy.h中声明为内核端,等于 4。它在 UAPI 中,所以实际上你可以#include <linux/mempolicy.h>.

MPOL_LOCAL 应该在numaif.h中声明为用户端,就像在手册页中一样。我不明白为什么它不是,以及其他定义。MPOL_MAX 的定义也发生了变化 - 内核方面它等于MPOL_LOCAL + 1 = 5,但在 numaif.h 中它等于MPOL_INTERLEAVE = 3。我希望 MPOL_MAX 比最大 MPOL 大一或两边的最大值相等,但是内核和用户空间工具对它的定义不同。

我认为应该向numactl发布问题以通知开发人员。根据手册页,它应该定义。我不知道为什么不是。

至于现在,我只想

#include <numaif.h>
#ifndef MPOL_LOCAL
#define MPOL_LOCAL 4
#endif

我浏览了网络以了解不同的程序如何处理这个问题。我认为程序只是自己定义所有 MPOL_* 符号,请参阅hwlocstress-ngfio刚刚将 MPOL_LOCAL 自己定义为相等 4. Open-mpi 甚至标记numaif.h未定义 MPOL_LOCAL 并且他们需要定义它,请参见此处


推荐阅读