我有几个自定义分配器,它们提供了基于不同策略分配内存的不同方法。其中之一在定义的 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/

    10-11 18:55