我有几个自定义分配器,它们提供了基于不同策略分配内存的不同方法。其中之一在定义的 NUMA 节点上分配内存。分配器的接口(interface)很简单
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()
。两种可能的解决方案:
memcpy()
hwloc_set_membind_nodeset()
为节点集设置内存分配/绑定(bind)策略,并使用普通的 malloc()
/posix_memalign()
和 realloc()
。 谁能帮我解决这个问题?
更新:
我试图让问题更具体:是否有可能使用
realloc()
执行 hwloc
而不分配新内存和移动页面? 最佳答案
要回复编辑:
hwloc 中没有 realloc,我们目前也没有添加的计划。如果您确切地看到了您想要的东西(函数的 C 原型(prototype)),请随时向 https://svn.open-mpi.org/trac/hwloc 添加一张票
回复 ogsx:内存绑定(bind)不是特定的,它是特定于虚拟内存区域的,并且可能是特定于线程的。如果你重新分配,libc 不会做任何特别的事情。
1)如果它可以在同一页面内重新分配,则您将在同一节点上获得内存。很好,但很少见,尤其是对于大型缓冲区。
2)如果它在不同的页面中重新分配(大多数情况下对于大缓冲区),这取决于过去 malloc lib 是否已经在物理内存中分配了相应的页面(在虚拟内存中进行了分配和释放,但是仍然分配在物理内存中)
2.a) 如果虚拟页面已被分配,过去可能由于各种原因在另一个节点上分配了它,你就搞砸了。
2.b) 如果新的虚拟页还没有分配,默认是在当前节点上分配。如果您之前使用 set_area_membind() 或 mbind() 指定了绑定(bind),它将在正确的节点上分配。在这种情况下,您可能会很高兴。
简而言之,这取决于很多事情。如果您不想打扰 malloc lib 做复杂/隐藏的内部事情,特别是如果您的缓冲区很大,那么使用 mmap(MAP_ANONYMOUS) 而不是 malloc 是一种确保在您真正需要时分配页面的简单方法他们。你甚至可以让 mremap 做一些类似于 realloc 的事情。
alloc 变成 mmap(length) + set_area_membind
realloc 变成了 mremap + set_area_membind(在整个 mremap'ed 缓冲区上)
从来没有用过,但看起来很有趣。
关于c++ - realloc() 用于使用 HWLOC 的 NUMA 系统,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6933129/