linux c绑定cpu_鲲鹏性能优化十板斧 | CPU与内存子系统性能调优

本文介绍了Linux环境下,通过CPU绑定、NUMA优化、预取开关修改、定时器调整以及内存页大小和线程并发数的调整来提升性能的方法。重点讲解了如何减少跨NUMA访问内存,调整CPU的预取设置,以及如何利用top、Perf和numactl工具进行性能监测。
摘要由CSDN通过智能技术生成

8c14bac56e423b5da03d0bb5e94662ad.png 特战队六月底成立,至今百日有余,此系列文章希望能为广大在鲲鹏处理器上开发软件、性能调优的程序员们,提供一点帮助。本篇主要介绍CPU与内存子系统性能调优。 bd79579d5d72da6c62f50f2836dcba72.png 1.CPU与内存子系统性能调优简介

调优思路

性能优化的思路如下:★ 如果CPU的利用率不高,说明资源没有充分利用,可以通过工具(如strace)查看应用程序阻塞在哪里,一般为磁盘,网络或应用程序的业务处理中存在休眠或信号等待,这些优化措施在后续其它章节描述。 ★如果CPU利用率高,通过优化软件硬件的配置参数来更好适配业务场景,减少CPU占用率,让整个系统有更多的CPU时间来处理业务。 我们也可以选择更好的硬件,根据CPU的能力配置合适的内存条,建议内存满通道配置,发挥内存最大带宽:一颗鲲鹏920处理器的内存通道数为8,两颗鲲鹏920处理器的内存通道数为16;建议选择高频率的内存条,提升内存带宽:鲲鹏920在1DPC配置时,支持的内存最高频率为2933MHz。

主要优化参数:

e3caf3b0a6b30e6b11eb2565d13b74e9.png

bd79579d5d72da6c62f50f2836dcba72.png

2.常用性能监测工具

2.1 top工具

介绍: top是最常用的Linux性能监测工具之一。通过top工具可以监视进程和系统整体性能。 命令参考举例:
命令说明
top查看系统整体的CPU、内存资源消耗。
top执行后输入1查看每个CPU core资源使用情况。
top执行后输入F,并选择P选项查看线程执行过程中是否调度到其它CPU core。
top -p $PID -H查看某个进程内所有线程的CPU资源占用。
安装方式: 系统自带,无需安装。 使用方法: 步骤 1  :使用top命令统计整体CPU、内存资源消耗 3c5e6940d28ef1c01869021c11c0548b.png ★CPU项:显示当前总的CPU时间使用分布。
  • us表示用户态程序占用的CPU时间百分比。
  • sy表示内核态程序所占用的CPU时间百分比。
  • wa表示等待IO等待占用的CPU时间百分比。
  • hi表示硬中断所占用的CPU时间百分比。
  • si表示软中断所占用的CPU时间百分比。
通过这些参数我们可以分析CPU时间的分布,是否有较多的IO等待。在执行完调优步骤后,我们也可以对CPU使用时间进行前后对比。如果在运行相同程序、业务情况下CPU使用时间降低,说明性能有提升。 ★KiB Mem:表示服务器的总内存大小以及使用情况。 ★KiB Swap:表示当前所使用的Swap空间的大小。Swap空间即当内存不足的时候,把一部分硬盘空间虚拟成内存使用。如果当前所使用的Swap空间大于0,可以考虑优化应用的内存占用或增加物理内存。 步骤 2:在top命令执行后按1,查看每个CPU core的使用情况                            通过该命令可以查看单个CPU core的使用情况,如果CPU占用集中在某几个CPU core上,可以结合业务分析触发原因,从而找到优化思路。 4e3b510607b0865c2c963c427f872f74.png 步骤 3:选中top命令的P选项,查看线程运行在哪些 CPU core上  在top命令执行后按F,可以进入top命令管理界面。在该界面通过上下键移动光标到P选项,通过空格键选中后按Esc退出,即可显示出线程运行的CPU核。观察一段时间,若业务线程在不同NUMA节点内的CPU core上运行,则说明存在较多的跨NUMA访问,可通过NUMA绑核进行优化。 c40ec8209e7e45ed3e66ebcf9ebb71f8.png 9298c43f3e3e2c849614bbce3ce8db66.png 步骤 4:使用top -p $PID -H命令观察进程中每个线程的CPU资源使用  “-p”后接的参数为待观察的进程ID。通过该命令可以找出消耗资源多的线程,随后可根据线程号分析线程中的热点函数、调用过程等情况。 5e874b3bdc0392a202c1a050ca0ca072.png ----结束

2.2 Perf工具

介绍: Perf工具是非常强大的Linux性能分析工具,可以通过该工具获得进程内的调用情况、资源消耗情况并查找分析热点函数。 命令参考举例:
命令说明
perf top查看当前系统中的热点函数。
perf sched record -- sleep 1 -p $PID记录进程在1s内的系统调用。
perf sched latency --sort max查看上一步记录的结果,以调度延迟排序。
安装方式: 以CentOS为例,使用如下命令安装: # yum -y install perf 使用方法: 步骤 1:通过perf top命令查找热点函数        该命令统计各个函数在某个性能事件上的热度,默认显示CPU占用率,可以通过“-e”监控其它事件。 l   Overhead表示当前事件在全部事件中占的比例。 l   Shared Object表示当前事件生产者,如kernel、perf命令、C语言库函数等。 l   Symbol则表示热点事件对应的函数名称。 通过热点函数,我们可以找到消耗资源较多的行为,从而有针对性的进行优化。 e1197af426568547eb674ea6ed22fb9b.png 步骤 2 :收集一段时间内的线程调用 perf sched record命令用于记录一段时间内,进程的调用情况。“-p”后接进程号,“sleep”后接统计时长,单位为秒。收集到的信息自动存放在当前目录下,文件名为perf.data。 a208eb4cb6fafd5f7b274503b3a0c2d9.png 步骤 3 :解析收集到的线程调度信息 perf sched latency命令可以解析当前目录下的perf.data文件。“-s”表示进行排序,后接参数“max”表示按照最大延迟时间大小排序。 b914911690a3e9a0a2ccd94614daf00d.png ----结束

2.3 numactl工具

介绍: numactl工具可用于查看当前服务器的NUMA节点配置、状态,可通过该工具将进程绑定到指定CPU core,由指定CPU core来运行对应进程。 命令参考举例:
命令说明
numactl -H查看当前服务器的NUMA配置。
numactl -C 0-7 ./test将应用程序test绑定到0~7核运行。
numastat查看当前的NUMA运行状态。
安装方式: 以CentOS为例,使用如下命令安装: # yum -y install numactl numastat 使用方法: 步骤 1:通过numactl查看当前服务器的NUMA配置。 从numactl执行结果可以看到,示例服务器共划分为4个NUMA节点。每个节点包含16个CPU core,每个节点的内存大小约为64GB。同时,该命令还给出了不同节点间的距离,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。 ba41439c051a0c1f2e57ccf08fd84bb1.png 步骤 2 :通过numactl将进程绑定到指定CPU core。 通过 numactl -C 0-15 top 命令即是将进程“top”绑定到0~15 CPU core上执行。 41c42f144e8a5e610bd687cb7b23a921.png 步骤 3 :通过numastat查看当前NUMA节点的内存访问命中率。 d9326f1f18bc538a4cea85df07d8f150.png 可以通过numastat命令观察各个NUMA节点的状态。 ★ numa_hit表示节点内CPU核访问本地内存的次数。 ★numa_miss表示节点内核访问其他节点内存的次数。跨节点的内存访问会存在高延迟从而降低性能,因此,numa_miss的值应当越低越好,如果过高,则应当考虑绑核。 ----结束 bd79579d5d72da6c62f50f2836dcba72.png

3.优化方法

3.1 NUMA优化,减少跨NUMA访问内存

原理: 通过《鲲鹏处理器NUMA简介》章节可以看到不同NUMA内的CPU core访问同一个位置的内存,性能不同。内存访问延时从高到低为:跨CPU > 跨NUMA不跨CPU > NUMA内, 因此在应用程序运行时要尽可能的避免跨NUMA访问内存,我们可以通过设置线程的CPU亲和性来实现。 修改方式: ★网络可以通过如下方式绑定运行的CPU core,其中$cpuMask是16进制的数,最右边的bit表示core0;$irq为网卡队列中断号。 echo $cpuMask > /proc/irq/$irq/smp_affinity_list ★通过numactl启动程序,如下面的启动命令表示启动test程序,只能在CPU core 28到core31运行(-C控制)。 numactl -C 28-31 ./test ★在C/C++代码中通过sched_setaffinity函数来设置线程亲和性。 ★很多开源软件已经支持在自带的配置文件中修改线程的亲和性,例如nginx可以修改nginx.conf文件中的worker_cpu_affinity参数来设置nginx线程亲和性。

3.2 修改CPU的预取开关

原理: 局部性原理分为时间局部性原理和空间局部性原理: ★时间局部性原理(temporal locality):如果某个数据项被访问,那么在不久的将来它可能再次被访问。 ★空间局部性原理(spatial locality):如果某个数据项被访问,那么与其地址相邻的数据项可能很快也会被访问。 CPU将内存中的数据读到CPU的高速缓冲Cache时,会根据局部性原理,除了读取本次要访问的数据,还会预取本次数据的周边数据到Cache里面,如果预取的数据是下次要访问的数据,那么性能会提升,如果预取的数据不是下次要取的数据,那么会浪费内存带宽。 对于数据比较集中的场景,预取的命中率高,适合打开CPU预取,反之需要关闭CPU预取。目前发现speccpu和X265软件场景适合打开CPU预取,STREAM测试工具、Nginx和数据库场景需要关闭CPU预取。 修改方式: 按照B 进入BIOS界面的步骤进入BIOS,然后在BIOS的如下位置设置CPU的预取开关。 82d09c96ddf1ba7fc4291b6bd56e1e72.png

3.3 定时器机制调整,减少不必要的时钟中断

原理: 在Linux内核2.6.17版本之前,Linux内核为每个CPU设置一个周期性的时钟中断,Linux内核利用这个中断处理一些定时任务,如线程调度等。这样导致就算CPU不需要定时器的时候,也会有很多时钟中断,导致资源的浪费。Linux 内核2.6.17版本引入了nohz机制,实际就是让时钟中断的时间可编程,减少不必要的时钟中断。 修改 方式 执行cat /proc/cmdline查看Linux 内核的启动参数,如果有nohz=off关键字,说明nohz机制被关闭,需要打开。修改方法如下: 说明: 修改前后,可以通过如下命令观察timer_tick的调度次数,其中$PID为要观察的进程ID,可以选择CPU占用高的进程进行观察: perf sched record -- sleep 1 -p $PID perf sched latency -s max 输出信息中有如下信息,其中591字段表示统计时间内的调度次数,数字变小说明修改生效。 timer_tick:(97) | 7.364 ms | 591 | avg: 0.012 ms | max: 1.268 ms 步骤 1:在“/boot”目录下通过find -name grub.cfg找到启动参数的配置文件。 步骤 2:在配置文件中将nohz=off去掉。 步骤 3:重启服务器。 ----结束

3.4 调整内存页的大小为64K,提升TLB命中率

原理: TLB(Translation lookaside buffer)为页表(存放虚拟地址的页地址和物理地址的页地址的映射关系)在CPU内部的高速缓存。TLB的命中率越高,页表查询性能就越好。 TLB的一行为一个页的映射关系,也就是管理了一个页大小的内存: TLB管理的内存大小 = TLB行数 x 内存的页大小 同一个CPU的TLB行数固定,因此内存页越大,管理的内存越大,相同业务场景下的TLB命中率就越高。 修改方式: 修改Linux内核编译选项,并重新编译: 说明: 修改前后可以通过如下命令观察TLB的命中率($PID为进程ID): perf stat -p $PID -d -d -d 输出结果包含如下信息,其中1.21%和0.59%分别表示数据的miss率和指令的miss率。 1,090,788,717      dTLB-loads                #  520.592 M/sec 13,213,603      dTLB-load-misses          #    1.21% of all dTLB cache hits 669,485,765      iTLB-loads                #  319.520 M/sec 3,979,246      iTLB-load-misses          #    0.59% of all iTLB cache hits 步骤 1:执行make menuconfig。 步骤 2:选择PAGESIZE大小为64K。 Kernel Features-->Page size(64KB) 步骤 3 :编译和安装内核。 参考https://bbs.huaweicloud.com/forum/thread-24362-1-1.html ----结束

3.5 调整线程并发数

原理: 程序从单线程变为多线程时,CPU和内存资源得到充分利用,性能得到提升。但是系统的性能并不会随着线程数的增长而线性提升,因为随着线程数量的增加,线程之间的调度、上下文切换、关键资源和锁的竞争也会带来很大开销。当资源的争抢比较严重时,甚至会导致性能明显降。下面数据为某业务场景下,不同并发线程数下的TPS,可以看到并发线程数达到128后,性能达到高峰,随后开始下降。我们需要针对不同的业务模型和使用场景做多组测试,找到适合本业务场景的最佳并发线程数。 039f10734acf728dbe7d7c822a7e25a8.png 修改方式: 不同的软件有不同的配置,需要根据代码实现来修改,这里举例几个常用开源软件的修改方法:
  • MySql可以通过innodb_thread_concurrency设置工作线程的最大并发数。
  • Nginx可以通过worker_processes参数设置并发的进程个数。

往期回顾: 《鲲鹏性能优化十板斧之前言 | 鲲鹏处理器NUMA简介与性能调优五步法》 下期预告: 《鲲鹏性能优化十板斧 | 网络子系统性能调优》 《鲲鹏性能优化十板斧 | 磁盘IO子系统性能调优》 《鲲鹏性能优化十板斧 | 应用程序调优》
大事件预告 4623e26ef237aba502302a767907581e.png @All开发者,想获取满满的技术干货吗?想了解最前沿的技术洞察吗?想得到最权威的学习认证吗?还有多维的交流平台以及有趣的有奖互动? 2020年华为开发者大会将于2月11-12日在深圳举办,这将是华为面向开发者群体的最顶级盛会,包含但不限于华为在云计算、人工智能、5G、IoT等多个领域,特别是智能计算双引擎鲲鹏和昇腾的最新创新与最佳实践,充满期待对吧,持续关注华为开发者社区,我们将为您带来关于HDC2020的更多精彩! 306cd0a3b0791be9921ca2c785f3c465.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值