0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

numactl内存绑定中代码段的问题

Linux阅码场 来源:Linux阅码场 作者:宋宝华 2021-05-10 14:20 次阅读

numactl内存绑定中代码段的问题

代码段为什么没有进入指定的numa节点

内核内存管理一个改进方向建议

在一个典型的NUMA架构Linux服务器中,我们常常使用类似numactl -N 1 -m 1 。/a.out类似的命令来绑定一定进程的memory,比如上面的例子,进程的memory被绑定到NUMA1。

但是这个时候,我们用numastat命令去查看进程a.out的内存分布,很可能会发现它有少部分内存不在NUMA1:

f1f6365c-b03c-11eb-bf61-12bb97331649.png

有极少量0.75MB在NUMA0。这是不是说numactl -m 1没有起作用呢?瞎猜没用,眼见为实,我们来调查一下这个在NUMA0的内存属于进程的哪一部分。

f2253d3a-b03c-11eb-bf61-12bb97331649.png

基本上可以看出,有3个地方有位于N0的内存,比如:

开始地址是0x40000的,文件背景为/root/a.out的部分;

开始地址是0x7fb9afc000,文件背景为/lib/aarch64-linux-gnu/libc-2.23.so的部分;

开始地址为0x7fb9c42000,文件背景为/lib/aarch64-linux-gnu/ld-2.23.so的部分。

如果我们进一步探究,会发现上面这三段,都是代码段:

f234b1a2-b03c-11eb-bf61-12bb97331649.png

为什么会这样呢?看起来numactl -m 《node》对代码段不起作用?

代码段为啥没进入指定numa?

原因其实是比较清晰的。上述代码段对应的内存,在Linux内核中,都属于有文件背景的页面,受page cache机制管理。

想象一个场景,如果a.out曾经运行过一次(其实我开机后已经在没有用numactl绑定内存的情况下,运行过一次a.out,上面的数据是第二次运行a.out的时候采集的),然后系统也加载了一些动态库,那么a.out本身的代码段,库的代码段可能进入到了numa节点m,从而在内存命中。接下来,如果我们用numactl -m 《n》 。/a.out去运行a.out并绑定numa节点n,势必要再次需要a.out的代码段以及a.out依赖的动态库的代码段。但是前一次,这些代码段都进入了page cache(位于NUMA node m),所以第2次在numa node n运行的时候,其实是命中了numa node m里面的内存。

假设我们运行4个a.out,这4个a.out分别运行于4个不同的numa,然后a.out依赖a.out的代码段、libx.so代码段,liby.so代码段。那么,完全有可能出现下图的情况,a.out的代码段位于numa0,libcx.so代码段位于numa1,liby.so的代码段位于numa2,这样4份运行中的a.out,都各自有跨NUMA的代码段内存访问,这样在icache替换的时候,都需要跨NUMA访问内存。

f261c278-b03c-11eb-bf61-12bb97331649.png

内核为什么这样做呢?原因在于,page cache的管理机制是以inode为单位的,每个page inode唯一!一个inode(比如a.out对应的inode)的page cache在内存命中的情况下,内核会直接用这部分page cache。这个page cache,不会为每个NUMA单独复制一份。从page cache的管理角度来讲,这没有问题。

我们把前面的a.out kill掉,然后drop一次cache,再看a.out的内存分布,发现在node0的部分减少了(0.75-》0.63)

f26b1508-b03c-11eb-bf61-12bb97331649.png

为什么呢?因为我drop掉部分page cache后(echo 3也不可能drop掉全部的所有的代码段,毕竟这里面很多代码是“活跃”代码),我们再运行a.out并绑定numa1的时候,这次这些没有命中的代码段page cache,会进入到numa1。

如果我们重启系统,开机第一次运行a.out就绑定numa1呢?这个时候,我们会看到a.out的代码段在numa1:

f27806c8-b03c-11eb-bf61-12bb97331649.png

然后我们把a.out kill掉,第二次绑定numa node0运行a.out,会发现这次的a.out的代码段还是在numa node1而不是node0:

f2bde5d0-b03c-11eb-bf61-12bb97331649.png

原因是它命中了第一次运行a.out已经进入node1的代码段page cache。

初恋为什么如此刻骨铭心,你终究还是错过了那个人,而多少年以后,常常回想起来,你依然泪流满面?因为,它命中了你的page cache。但是终究,一个人,一生可能不会只运行一次a.out。我们终究也要学会放手,把全部的爱,献给你身边与你相濡以沫的那个人。

内存管理的改进方向

2020年8月,我在Linux内核里面提交和合入了per-numa CMA的支持:

dma-contiguous: provide the ability to reserve per-numa CMA

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b7176c261cdbc

这样让每个NUMA里面的外设申请连续内存的时候,可以申请到本NUMA的近地址内存,而不用跑到远端去,从而提高I/O的性能:

f3421ef4-b03c-11eb-bf61-12bb97331649.png

考虑到代码段以及其他page cache的跨NUMA特点,这里我想提一个可能性,就是per-numa Page cache。内核可以支持让关键的代码段,文件背景页面,在每个NUMA单独获得一份page cache:

f35a3e3a-b03c-11eb-bf61-12bb97331649.png

它的缺点是显而易见的,page cache可能会用多份内存。它的优点也是显而易见的,就是代码段不用跨NUMA了。这属于典型的以空间换时间!

这个事情行不行得通呢?技术上是行得通的,实践上,我是不敢做的,因为需要大量的benchmark,加上patch至少得发20,30个版本,前后一两年至少的。别的不说,宋牧春童鞋的省vmemmap内存的patch已经发到了22版:

[PATCH v22 0/9] Free some vmemmap pages of HugeTLB page

https://lore.kernel.org/lkml/20210430031352.45379-1-songmuchun@bytedance.com/

要是干这个page cache的优化,不得至少发个30版?通常这种有利于全世界,而不利于自己的KPI的事情,是没有多少工程师愿意投入的 :-) 细思恐极,这需要极大的耐心、投入和奉献精神。

那么,前期是不是可以从一个小点开始优化呢?我觉得是可能的。

比如a.out本身在numa0运行,kill后再在numa1运行,这个时候,内核感知到a.out独一份,没有share的情况,是不是直接在内核态把page cache直接migrate到numa1呢?我这里还是打个嘴炮就好,把想象空间留给读者。

原文标题:宋宝华:为什么numactl内存绑定对代码段不起作用

文章出处:【微信公众号:Linuxer】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2767

    浏览量

    72779
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66820

原文标题:宋宝华:为什么numactl内存绑定对代码段不起作用

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    服务器宝塔面板怎么绑定多个ip?

    服务器宝塔面板怎么绑定多个ip?在宝塔面板中绑定多个IP地址可以通过以下步骤完成: 1、登录宝塔面板 使用你的浏览器访问宝塔面板的网址,并使用管理员账号和密码登录。 2、进入站点管理 在宝塔面板左侧
    的头像 发表于 01-12 17:29 652次阅读

    求教下source insight 的使用问题,关于#if #endif中的代码变暗的

    source insight 4.0在实际使用时,#if 0#endif会使中间的代码变暗,但假如我的#if 0是通过宏定义的,如图的IOT_PTINTF_TEST为0,代码就不会
    发表于 12-08 11:06

    如何绑定ip地址与mac物理地址呢?

    如何绑定ip地址与mac物理地址呢? 绑定IP地址与MAC物理地址是一种网络管理和安全措施,可以帮助确保网络设备的身份验证和安全性。在这篇文章中,我们将详细介绍如何进行IP地址与MAC物理地址的绑定
    的头像 发表于 12-07 09:33 1296次阅读

    Linux内核驱动与单个PCI设备的绑定和解绑定

    在Linux内核2.6.13-rc3以前,驱动和设备之间的绑定和解绑只能通过insmod(modprobe)和rmmod来实现,但是这种实现方法有一个弊端,就是一旦绑定或者解绑定都是针对驱动与其
    的头像 发表于 11-17 17:11 833次阅读
    Linux内核驱动与单个PCI设备的<b class='flag-5'>绑定</b>和解<b class='flag-5'>绑定</b>

    labview 数据绑定求助

    求助 LABVIEW 大神 在每个控件属性中有一个数据绑定绑定到本机的OPC服务器上 是正常可以用的如果我想把这个绑定路径做成根我提供的字符串路径动态绑定的这个该怎么实现
    发表于 10-24 09:19

    谁知道FatFs中代码页存在的意义是什么?

    FatFs中代码页存在的意义是什么?
    发表于 10-16 07:58

    车规模块系列(五):聊一聊DBB/铜绑定技术

    相对于传统的铝绑定线工艺,铜绑定线需要对芯片表面进行要求更高的金属化,而丹佛斯键合缓冲Danfoss Bond Buffer (DBB)技术就是为了铜绑定线进行的表面处理。
    的头像 发表于 10-08 10:22 1047次阅读
    车规模块系列(五):聊一聊DBB/铜<b class='flag-5'>绑定</b>技术

    如何使用valgrind对代码进行内存泄露检测

    代码可能存在 内存泄露 怎么办? 使用 valgrind 可以对代码进行内存泄露检测。 valgrind下载安装 安装: 1 、tar –jxvf valgrind- 3 . 21
    的头像 发表于 10-04 14:56 398次阅读
    如何使用valgrind对<b class='flag-5'>代码</b>进行<b class='flag-5'>内存</b>泄露检测

    使用valgrind对代码进行内存泄露检测

    代码可能存在内存泄露怎么办?
    发表于 08-21 15:30 173次阅读
    使用valgrind对<b class='flag-5'>代码</b>进行<b class='flag-5'>内存</b>泄露检测

    基于C++代码实现内存泄漏检测工具

    看到的一个文章,有人用一个很简短的代码实现了内存检测工具,大家看看实用性如何?
    发表于 08-21 10:11 283次阅读
    基于C++<b class='flag-5'>代码</b>实现<b class='flag-5'>内存</b>泄漏检测工具

    兼顾内存和速度的C语言代码优化的方法

    在本篇文章中,我(指原作者)收集了很多经验和方法。应用这些经验和方法,可以帮助我们从执行速度和内存使用等方面来优化C语言代码
    发表于 07-24 15:44 281次阅读
    兼顾<b class='flag-5'>内存</b>和速度的C语言<b class='flag-5'>代码</b>优化的方法

    教程 5:配对、绑定和安全

    教程 5:配对、绑定和安全
    发表于 07-06 18:49 0次下载
    教程 5:配对、<b class='flag-5'>绑定</b>和安全

    什么是堆内存?存储方式是什么样的?

    只有在堆内存里面才会发生内存泄漏的问题,在栈内存中不会发生内存泄漏。因为栈内存在自动分配空间之后,还会自动释放空间。 什么是堆
    的头像 发表于 06-22 10:29 772次阅读
    什么是堆<b class='flag-5'>内存</b>?存储方式是什么样的?

    sram内存块不适合mcal_bss怎么解决?

    对于我的项目,我使用带有 EBTresos 的 S32K342 进行配置和 Autosar OS。我面临如下 sram内存块不适合 mcal_bss 问题。 链接 main.elf
    发表于 05-19 08:31

    gstreamer采用waylandsink并绑定到QWidget失败?

    ,现在测试一直绑定失败,请问什么原因啊,我的绑定代码如下:   另外,我也进行测试,但是这种方式虽然在我设置界面透明之后能够播放,但是不符合我的需求,请问需要如何去进行绑定我的视频界
    发表于 05-11 16:01