realloc()的使用HWLOC
NUMA系统我有一个提供不同的装置根据不同的策略来分配内存中的几个自定义的分配。其中一个在定义的NUMA节点上分配内存。到分配器的接口是直截了当realloc()的使用HWLOC
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()
方法有用于分配策略等Howver,hwloc仅提供分配和free'ing存储器和I的方法设置的参数,根据处理想知道我应该如何实施reallocate()
。
两个可能的解决方案:
- 分配新的内存区域和
memcpy()
数据 - 使用
hwloc_set_membind_nodeset()
设置内存分配/结合政策的节点集,并使用纯malloc()
/posix_memalign()
和realloc()
。
谁能帮助我得到这个吧?
更新:
我努力使这个问题更具体:是否有执行可能性realloc()
使用hwloc
不分配新的内存,并四处移动网页?
的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
实现它的工作原理只有在区域页面并没有被感动,所以它是你的第二个解决方案移动存储区域只是比较正确的做法。 更新有一个MPOL_MF_MOVE *标志移动触摸的数据。
移动页面,而不再分配和复制我所知道的唯一的系统调用是move_pages
move_pages移动一组在运行进程的地址空间的页面为不同的NUMA节点。
正如你所说的'hwloc_set_area_membind_nodeset'只允许将分配的内存移动到另一个节点,而我在'libnuma'中寻找类似'numa_realloc()'的东西。 – grundprinzip
你错了。 mbind可以移动已被触摸的页面。你只需要添加MPOL_MF_MOVE。这就是hwloc_set_area_membind_nodeset()
如果你添加标志HWLOC_MEMBIND_MIGRATE
。
move_pages
只是一个不同的方式来做到这一点(更灵活,但有点慢,因为你可以将独立页面移动到不同的地方)。与MPOL_MF_MOVE
和move_pages(以及migrate_pages)的mbind最后在mm/migrate.c中使用完全相同的migrate_pages()
函数,一旦它们将输入转换为页面列表。
因此,grundprinzip可以做一个通常的realloc,然后用'HWLOC_MEMBIND_MIGRATE'调用'hwloc_set_area_membind_nodeset()'? – osgx
是的。 或者他也可以执行hwloc_alloc_membind_nodeset()来在正确的内存节点上分配新的缓冲区,然后手动将memcpy从旧的缓冲区移动到新的缓冲区,然后释放旧的缓冲区。无论如何,你必须复制一些内容,所以最好在绑定最终缓冲区后进行复制。 – Brice
我知道可以迁移页面,但正如问题中所述,我想增加分配的内存区域,并希望避免复制。 – grundprinzip
要回复编辑: hwloc中没有realloc,我们目前没有计划添加一个。如果你首先看到你想要的东西(C函数的原型),随时添加一张票https://svn.open-mpi.org/trac/hwloc
回复ogsx:内存绑定不是特定的,它是虚拟内存区域特定的,具体。如果你重新分配,libc不会做任何特殊的事情。 1)如果它可以在同一页面内重新分配,则在同一节点上获得内存。好,但很少见,特别是对于大型缓冲区。 2)如果它重新分配在一个不同的页面(大多数情况下是大缓冲区),它取决于相应的页面是否已经被malloc lib在物理内存中分配过了(malloc在virtual memory中被释放,但仍然分配在物理内存中) 2.a)如果已经分配了虚拟页面,则可能由于各种原因在另一个节点上分配了虚拟页面。 2.b)如果尚未分配新的虚拟页面,则默认为在当前节点上分配。如果您先前使用set_area_membind()或mbind()指定了绑定,它将分配到正确的节点上。在这种情况下你可能会很高兴。
总之,这取决于很多事情。如果你不想用malloc lib做复杂/隐藏的内部事情,特别是如果你的缓冲区很大,做mmap(MAP_ANONYMOUS)而不是malloc是一种简单的方法,以确保在你真正想要的时候分配页面他们。你甚至有mremap做类似于realloc的东西。
ALLOC变得MMAP(长度)+ set_area_membind realloc的变mremap + set_area_membind(对整个mremap'ed缓冲器)
从未使用过,但看起来有趣。
直接使用libnuma怎么样? http://linux.die.net/man/3/numa – osgx
因为'libnuma'可能会产生错误的结果(显示numa节点等错误的cpu绑定),我希望使用'hwloc'代替。 https://gist.github.com/1125022 – grundprinzip
嗯..是内存绑定设置节点特定的?那么,如果节点5调用内存中的realloc(由节点5拥有),libc的realloc会执行同节点内存分配吗? – osgx