使用HWLOC的NUMA系统的realloc()

我有几个自定义分配器,提供不同的方式来分配基于不同的策略的内存。 其中一个在已定义的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只提供了分配和释放内存的方法,我想知道应该如何实现reallocate()

两种可能的解决方

  1. 分配新的内存区域和memcpy()数据
  2. 使用hwloc_set_membind_nodeset()来设置节点集的内存分配/绑定策略,并使用普通的malloc() / posix_memalign()realloc()

任何人都可以帮助我得到这个权利?

更新:

我试图使问题更具体:是否有可能使用hwloc执行realloc()而不分配新的内存并移动页面?

Solutions Collecting From Web of "使用HWLOC的NUMA系统的realloc()"

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)标识的已经分配的内存绑定到nodeset中的NUMA节点。

返回:

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

在linux上,这个调用是通过mbind来实现的只有当这个区域中的页面没有被触摸的mbind它才起作用,所以在第二个解决方案中移动内存区域只是更正确的方法。 更新有一个MPOL_MF_MOVE *标志来移动触摸的数据。

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

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

你错了。 mbind可以移动已经被触摸的页面。 你只需要添加MPOL_MF_MOVE。 这就是hwloc_set_area_membind_nodeset()如果添加标志HWLOC_MEMBIND_MIGRATE

move_pages只是一个不同的方式来做到这一点(更灵活,但有点慢,因为你可以将独立页面移动到不同的地方)。 mbind与MPOL_MF_MOVE和move_pages(以及migrate_pages migrate_pages()在mm / migrate.c中使用MPOL_MF_MOVE migrate_pages( migrate_pages()函数,一旦它们将输入转换为页面列表。

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

要回复ogsx:内存绑定不是特定的,它是虚拟内存区域特定的,并且可能是线程特定的。 如果你重新分配,libc不会做任何特殊的事情。 1)如果它可以在同一页面内重新分配,则在相同的节点上获得内存。 好,但很少,特别是对于大型缓冲区。 2)如果它重新分配在一个不同的页面中(大多数情况下是大缓冲区),这取决于相应的页面是否已经被malloc lib在物理内存中分配过去了(在malloc中被释放,仍然分配在物理内存中)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缓冲区中)

从来没有用过,但看起来有趣。