首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >numactl & perf如何改变子进程的内存放置策略?

numactl & perf如何改变子进程的内存放置策略?
EN

Stack Overflow用户
提问于 2020-06-26 23:46:15
回答 1查看 1.9K关注 0票数 1

我注意到numactl对流基准有一些奇怪的影响

更具体地说,"numactl ./stream_c.exe“报告的内存带宽比"./stream_c.exe”低40%。

我检查了numactl 源代码,没有看到任何特殊的东西,如果我不给它任何参数,它应该做什么。因此,我天真地期望numactl在"numactl ./stream_c.exe“中不会对性能产生影响,根据我的实验,这是不正确的。

这是一个具有高核心计数处理器的双套接字服务器.

使用numastat,我可以看到numactl命令导致内存分配不平衡:两个numa节点将内存分配除以80:20。

如果没有numactl,内存将以非常均衡的方式分配: 46:54。

我还发现,这不仅仅是一个数字问题。如果我使用perf来调用stream_c.exe,那么内存分配甚至比使用numactl更不平衡。

因此,这更像是一个内核问题: numactl和perf如何更改子进程的内存放置策略?谢谢!

EN

回答 1

Stack Overflow用户

发布于 2020-06-27 20:09:35

TL;DR: -- numactl使用的默认策略--可能会导致性能问题以及OpenMP线程绑定。numactl约束应用于所有(分叉)子进程。

实际上,numactl默认使用预定义的策略。这个策略可以是--interleaved--preferred--membind--localalloc。当第一次触摸页面时,此策略将更改操作系统页分配的行为。以下是政策的含义:

  • --interleaved:内存页通过节点集指定的节点分配,但以循环方式分配;
  • --preferred:内存是从单个首选内存节点分配的。如果没有足够的内存,则可以从其他节点分配内存。
  • --membind:仅从节点分配内存。当这些节点上没有足够的可用内存时,分配将失败;
  • --localalloc:总是在当前节点上分配(执行内存页面第一次触摸的节点)。

在您的示例中,指定一个--interleaved --localalloc --localalloc策略的应该提供更好的性能。我想,如果线程被绑定到内核,那么--localalloc策略应该是最好的选择(参见下面)。

此外,默认情况下,STREAM_ARRAY_SIZE 宏被设置为一个太小的值 (10 Mo),无法实际测量RAM的性能。事实上,AMD 7742处理器有一个256 big L3高速缓存,它的大小足以满足所有基准数据。将结果与大于L3缓存的值进行比较可能要好得多(例如。1024米)。

最后,OpenMP线程可以从一个numa节点迁移到另一个节点。这会大大降低基准测试的性能,因为当线程移动到另一个节点时,访问的内存页位于远程节点上,目标NUMA节点可能会饱和。您需要绑定 OpenMP线程,以便它们不能使用这个特定处理器的以下环境变量移动:假定SMT已禁用且核心in在0-63范围内的OMP_NUM_THREADS=64 OMP_PROC_BIND=TRUE OMP_PLACES="{0}:64:1"。如果启用了SMT,则应该使用命令:OMP_PLACES (需要在机器上安装hwloc包)对OMP_PLACES={$(hwloc-calc --sep "},{" --intersect PU core:all.pu:0)}变量进行优化。您可以使用命令hwloc检查线程绑定。

更新:

numactl 影响所有子进程的NUMA属性(因为子进程是在Linux上使用fork创建的,因此应该复制NUMA属性)。您可以使用以下(bash)命令检查它:

代码语言:javascript
复制
numactl --show
numactl --physcpubind=2 bash -c "(sleep 1; numactl --show; sleep 2;) & (sleep 2; numactl --show; sleep 1;); wait"

这个命令首先显示NUMA属性。将其设置为并行启动2个进程的子bash进程。每个子进程都显示NUMA属性。在我的1节点机器上,结果如下:

代码语言:javascript
复制
policy: default                    # Initial NUMA attributes
preferred node: current
physcpubind: 0 1 2 3 4 5 
cpubind: 0 
nodebind: 0 
membind: 0 
policy: default                    # Sub-child 1
preferred node: current
physcpubind: 2 
cpubind: 0 
nodebind: 0 
membind: 0 
policy: default                    # Sub-child 2
preferred node: current
physcpubind: 2 
cpubind: 0 
nodebind: 0 
membind: 0 

在这里,我们可以看到--physcpubind=2约束被应用于两个子进程。在您的多节点机器上,--membind或NUMA策略应该是相同的。因此,请注意,在子进程之前调用perf不应该对NUMA属性产生任何影响。

perf不应直接影响分配。但是,操作系统的默认策略可以平衡每个NUMA节点上分配的内存数量。如果是这样的话,页面分配可能是不平衡的,因为NUMA节点的饱和会降低带宽。NUMA节点之间的OS内存页平衡非常敏感:在两个基准测试之间写入一个大型文件可能会影响第二次运行(从而影响基准测试的性能)。这就是为什么NUMA属性应该总是为(以及进程绑定)手动设置。

PS: i假设流基准已经通过OpenMP支持进行编译,并且也启用了优化(即。-fopenmp -O2 -march=native关于GCC和Clang)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62604334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档