繁体   English   中英

使用numa_alloc_onnode()分配小块是否有限制?

[英]Are there limits on allocating small chunks using numa_alloc_onnode()?

我正在一台拥有4台Operton 6272处理器,运行centOS的机器上试验NUMA。 有8个NUMA节点,每个节点有16GB内存。

这是我正在运行的一个小测试程序。

void pin_to_core(size_t core)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(core, &cpuset);
    pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
}

int main()
{
    pin_to_core( 0 );

    size_t bufSize = 100;
    for( int i = 0; i < 131000; ++i )
    {
        if( !(i % 10) )
        {
            std::cout << i << std::endl;
            long long free = 0;
            for( unsigned j = 0; j < 8; ++j )
            {
                numa_node_size64( j, &free );
                std::cout << "Free on node " << j << ": " << free << std::endl;
            }
        }

        char* buf = (char*)numa_alloc_onnode( bufSize, 5 );
        for( unsigned j = 0; j < bufSize; ++j )
            buf[j] = j;
    }

    return 0;
}

因此,基本上在核心#0上运行的线程在NUMA节点5上分配131K 100字节缓冲区,用垃圾初始化它们并泄漏它们。 每10次迭代,我们就会打印出每个NUMA节点上可用内存量的信息。

在输出的开头,我得到:

0
Free on node 0: 16115879936
Free on node 1: 16667398144
Free on node 2: 16730402816
Free on node 3: 16529108992
Free on node 4: 16624508928
Free on node 5: 16361529344
Free on node 6: 16747118592
Free on node 7: 16631336960
...

最后我得到了:

Free on node 0: 15826657280
Free on node 1: 16667123712
Free on node 2: 16731033600
Free on node 3: 16529358848
Free on node 4: 16624885760
Free on node 5: 16093630464
Free on node 6: 16747384832
Free on node 7: 16631332864
130970
Free on node 0: 15826657280
Free on node 1: 16667123712
Free on node 2: 16731033600
Free on node 3: 16529358848
Free on node 4: 16624885760
Free on node 5: 16093630464
Free on node 6: 16747384832
Free on node 7: 16631332864
mbind: Cannot allocate memory
mbind: Cannot allocate memory
mbind: Cannot allocate memory
mbind: Cannot allocate memory
mbind: Cannot allocate memory
mbind: Cannot allocate memory
mbind: Cannot allocate memory
130980
...

我不清楚的事情:

1)为什么有那些“mbind:无法分配内存”的消息? 事实上,如果我将缓冲区大小更改为1000,那么我远没有用尽所有内存并且行为不会改变,这让我觉得我的某些内核资源句柄已经用完了。

2)即使我要求在节点5上分配内存,实际分配似乎已在节点0和5之间分配。

任何人都可以提供任何有关为什么会发生这种情况的见解?

UPDATE

想提供关于第(2)点的更多细节。 部分内存未在节点5上分配的事实似乎与我们正在初始化核心#0(属于NUMA节点0)上的缓冲区这一事实有关。 如果我将pin_to_core(0)更改为pin_to_core(8)则在节点1和5之间分配分配的内存。如果是pin_to_core(40)则在节点5上分配所有内存。

UPDATE2

我查看了libnuma的源代​​码,并尝试使用更多低级调用替换对numa_alloc_onnode()调用: mmap()mbind() 我现在也在检查内存所在的NUMA节点 - 我使用move_pages()调用。 结果如下。 在初始化之前( j的循环),页面没有映射到任何节点(我得到ENOENT错误代码),并且在初始化之后,页面被分配给节点0或节点5.模式是常规的:5,0,5, 0,...和以前一样,当我们接近第131000次迭代时,对mbind()的调用开始返回错误代码,当发生这种情况时,页面总是被分配给节点0.mbind返回的错误代码是ENOMEM ,文档说这意味着用尽“内核内存”。 我不知道它是什么,但它不能是“物理”内存,因为我每个节点有16GB。

所以这是我目前的结论:

  1. 当另一个NUMA节点的核心首先触及内存时, mbind()强加的内存映射限制仅占50%。 我希望在某处记录这一点,因为悄悄地违背承诺并不好......

  2. mbind的调用次数有限制。 所以应该mbind()大内存块。

我要尝试的方法是:在固定到特定NUMA ndo核心的线程上执行内存分配任务。 为了更加安心,我将尝试调用mlock(因为此处描述的问题)。

正如您在阅读libnuma.c发现的libnuma.c ,每次调用numa_alloc_onnode()都会创建一个新的匿名内存映射,然后将内存区域绑定到指定的NUMA节点。 有了这么多的mmap()调用,你只需要达到每个进程允许的最大内存映射数。 该值可以从/proc/sys/vm/max_map_count ,也可以由系统管理员通过写入伪文件来修改:

# echo 1048576 > /proc/sys/vm/max_map_count

或者使用sysctl

# sysctl -w vm.max_map_count=1048576

Linux发行版的默认值为65530映射。 mmap()实现了映射合并,即它首先尝试在创建新映射之前扩展现有映射。 在我的测试中,它在每次调用时创建一个新映射,否则扩展前一个映射。 在第一次调用numa_alloc_onnode()之前,我的测试进程有37个映射。 因此,在2 * (65530-37) = 130986调用之后, mmap()应该开始失败。

看起来当mbind()应用于现有映射的一部分时,会发生奇怪的事情并且新受影响的区域未正确绑定。 我必须深入研究内核源代码以找出原因。 另一方面,如果你更换:

numa_alloc_onnode( bufSize, 5 )

numa_alloc_onnode( bufSize, i % 4 )

没有执行映射合并,并且mmap()在第65500次迭代周围失败,并且所有分配都被正确绑定。

第一个问题,来自numa_alloc_onnode的手册页

The size argument will be rounded up to a multiple of the system page size.

这意味着,虽然您要求少量数据,但您获得的是整页。 也就是说,在你的程序中,你实际上是在请求131000个系统页面。

对于您的第二个问题,我建议使用numa_set_strict()强制numa_alloc_onnode失败,如果它无法在给定节点上分配页面。

numa_set_strict() sets a flag that says whether the functions  allocating
   on specific nodes should use use a strict policy. Strict means the
   allocation will fail if the memory cannot be allocated  on  the  target
   node.   Default operation is to fall back to other nodes.  This doesn't
   apply to interleave and default.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM