【问题标题】:Can I get the NUMA node from a pointer address (in C on Linux)?我可以从指针地址(在 Linux 上的 C 中)获取 NUMA 节点吗?
【发布时间】:2011-12-20 16:13:33
【问题描述】:

我已将代码设置为在我的 NUMA 系统上小心地在本地加载和处理数据。我想。也就是说,出于调试目的,我真的希望能够使用在特定函数中访问的指针地址(由许多其他函数设置)来直接识别内存指向的 NUMA 节点居住在上面,所以我可以检查所有东西是否都位于它应该位于的位置。这可能吗?

我在 msdn http://social.msdn.microsoft.com/Forums/en-US/parallelcppnative/thread/37a02e17-e160-48d9-8625-871ff6b21f72 上发现了同样的请求,但答案使用的是 QueryWorkingSetEx(),它似乎是特定于 Windows 的。这可以在Linux上完成吗?准确地说,我正在使用 Debian Squeeze。

谢谢。

【问题讨论】:

    标签: c linux multithreading memory numa


    【解决方案1】:

    在内核模式下,我们可以使用lookup_node()

    【讨论】:

      【解决方案2】:

      如果您知道 mmap 返回的地址,请尝试检查/proc/{pid}/numa_maps。你会看到类似

      14ab47200000 interleave:2-3 anon=1171400 dirty=1171400 N2=585690 N3=585710 kernelpagesize_kB=4
      
      

      这意味着 0x14ab47200000 地址交错到节点 2 和节点 3(N3)。 详情请查看https://linux.die.net/man/5/numa_maps

      【讨论】:

        【解决方案3】:

        另外,-lnuma:http://linux.die.net/man/2/get_mempolicy 中有一个get_mempolicy 函数

        If flags specifies both MPOL_F_NODE and MPOL_F_ADDR, get_mempolicy() will 
        return the node ID of the node on which the address addr is allocated into 
        the location pointed to by mode. If no page has yet been allocated for the 
        specified address, get_mempolicy() will allocate a page as if the process had 
        performed a read [load] access to that address, and return the ID of the node 
        where that page was allocated. 
        

        因此,ptr 指向的页面的 numa 节点通过以下方式检查:

        int numa_node = -1;
        get_mempolicy(&numa_node, NULL, 0, (void*)ptr, MPOL_F_NODE | MPOL_F_ADDR);
        return numa_node;
        

        【讨论】:

        • 这两个函数(你的和接受的答案)是否有原因执行相同的行为?我什么时候应该互相使用?
        • get_mempolicy() 对我有用(但 move_pages() 不适用)。 Tho,似乎get_mempolicy() 无法在 1 次调用中获取多个内存地址的 NUMA 节点 ID。还是我错过了什么?
        【解决方案4】:

        -lnuma中有一个move_pages函数:http://linux.die.net/man/2/move_pages

        可以将地址(页面)的当前状态报告给节点映射:

        nodes 也可以为 NULL,在这种情况下 move_pages() 不会移动任何页面,而是会在状态数组中返回每个页面当前所在的节点。可能需要获取每个页面的状态以确定需要移动的页面。

        所以,调用可能是这样的:

         void * ptr_to_check = your_address;
         /*here you should align ptr_to_check to page boundary */
         int status[1];
         int ret_code;
         status[0]=-1;
         ret_code=move_pages(0 /*self memory */, 1, &ptr_to_check,
            NULL, status, 0);
         printf("Memory at %p is at %d node (retcode %d)\n", ptr_to_check, status[0], ret_code);
        

        【讨论】:

        • 使用你的答案我得到“致命错误:numaif.h:没有这样的文件或目录”。你知道出了什么问题吗?
        • 好的。我得到了它。 头文件不包含在 glibc 中,但需要安装 libnuma-devel 或类似的包。
        • @osgx 我试过你的代码。出于某种原因,status[0] 由move_pages() 填充,值为-2,即使我尝试首先将其初始化为-2147483648。任何想法?我尝试传递的地址是mmap()(带有多个 2MB 大页面)返回的内存地址(如果重要)。谢谢!
        • @HCSF,您能否打开一个附有完整示例的新问题?内核版本也是必需的。然后我会试着检查一下。
        • @osgx 我更新了我的post。谢谢!
        猜你喜欢
        • 2019-10-30
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        • 1970-01-01
        • 2015-09-10
        • 2017-06-19
        • 1970-01-01
        • 2011-03-19
        相关资源
        最近更新 更多