numaif.h: MPOL_LOCAL 未声明用于 mbind

numaif.h: MPOL_LOCAL undeclared for use in 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

改为例如MPOL_INTERLEAVE 使其编译和显示 Hello world! 就好了。

这是怎么回事?在这个阶段我百分百困惑。

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

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 大 1 或等于最大值,但内核和用户 space 工具对它的定义不同。

我认为 post 一个问题 numactl 通知开发者是值得的。根据手册页,它应该定义。我不知道为什么不是。

至于现在,我会

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

我浏览了网页以了解不同的程序如何处理此问题。我认为程序只是自己定义所有 MPOL_* 符号,请参阅 hwloc or stress-ng. fio just defined MPOL_LOCAL themself to be equal 4. Open-mpi even marks that numaif.h does not define MPOL_LOCAL and they need to define it, see here.