使用HWLOC的NUMA系统的realloc()

时间:2011-08-03 20:51:26

标签: c++ linux memory numa

我有几个自定义分配器,它们提供了不同的方法来根据不同的策略分配内存。其中一个在定义的NUMA节点上分配内存。分配器的接口是直接的

template<typename config>
class NumaNodeStrategy
{

public:

    static void *allocate(const size_t sz){}

    static void *reallocate(void *old, size_t sz, size_t old_sz){}

    static void deallocate(void *p, size_t sz){}
};

使用hwloc_alloc_membind_nodeset()方法处理分配本身,并为分配策略设置相应的参数等。但是,hwloc只提供分配和释放内存的方法,我想知道应该如何实现{{1 }}

两种可能的解决方案:

  1. 分配新的内存区域和reallocate()数据
  2. 使用memcpy()设置节点集的内存分配/绑定策略,并使用纯hwloc_set_membind_nodeset() / malloc()posix_memalign()
  3. 任何人都可以帮助我做到这一点吗?

    更新

    我尝试更具体地提出问题:是否有可能使用realloc()执行realloc()而无需分配新内存并移动页面?

3 个答案:

答案 0 :(得分:2)

回复编辑: hwloc中没有realloc,我们目前没有计划添加一个。如果你看到了你想要的东西(函数的C原型),可以随意添加一张票给https://svn.open-mpi.org/trac/hwloc

回复ogsx:内存绑定不是特定的,它是特定的虚拟内存区域,可能是特定于线程的。如果你重新分配,libc没有做任何特别的事情。 1)如果它可以在同一页面内重新分配,则会在同一节点上获得内存。好,但很少见,特别是对于大缓冲区。 2)如果它在一个不同的页面重新分配(大多数情况下是大缓冲区),它取决于过去的malloc lib是否已经在物理内存中分配了相应的页面(malloc'ed并在虚拟内存中释放,但是仍然在物理内存中分配) 2.a)如果已经分配了虚拟页面,它可能由于各种原因在过去分配到另一个节点上,你就搞砸了。 2.b)如果尚未分配新虚拟页面,则默认为在当前节点上分配。如果您之前使用set_area_membind()或mbind()指定了绑定,则它将在右侧节点上分配。在这种情况下你可能会很开心。

简而言之,这取决于很多事情。如果您不想使用malloc lib来执行复杂/隐藏的内部事务,特别是如果您的缓冲区很大,那么执行mmap(MAP_ANONYMOUS)而不是malloc是确保在您真正需要时分配页面的简单方法他们。你甚至可以使用mremap来做类似于realloc的事情。

alloc变为mmap(length)+ set_area_membind realloc变为mremap + set_area_membind(在整个mremap的缓冲区上)

从未使用过,但看起来很有趣。

答案 1 :(得分:1)

hwloc_set_area_membind_nodeset可以解决问题,不是吗?

 HWLOC_DECLSPEC int     
  hwloc_set_area_membind_nodeset (hwloc_topology_t topology, 
    const void *addr, size_t len, hwloc_const_nodeset_t nodeset, 
    hwloc_membind_policy_t policy, int flags)
  

将(addr,len)标识的已分配内存绑定到节点集中的NUMA节点。

     

返回:

  • -1,如果不支持该操作,则将errno设置为ENOSYS
  • -1,如果无法强制执行绑定,则将errno设置为EXDEV

在linux上,此调用是通过mbind实现的。只有在未触摸区域中的页面时才有效,因此在第二个解决方案中移动内存区域的方法更为正确。 UPDATE 有一个MPOL_MF_MOVE *标记来移动触摸的数据。

唯一没有重新分配和复制的移动页面的系统调用我知道move_pages

  

move_pages将已执行进程的地址空间中的一组页面移动到另一个NUMA节点。

答案 2 :(得分:1)

你错了。 mbind可以移动已被触摸的页面。您只需添加MPOL_MF_MOVE即可。这就是hwloc_set_area_membind_nodeset()添加标记HWLOC_MEMBIND_MIGRATE时的作用。

move_pages只是一种不同的方式(更灵活,但有点慢,因为你可以将独立的页面移动到不同的地方)。一旦将输入转换为页面列表,mbind MPOL_MF_MOVE和move_pages(以及migrate_pages)最终都会使用mm / migrate.c中完全相同的migrate_pages()函数。