1.1 CPU与内存子系统性能调优简介

调优思路

性能优化的思路如下:

l   如果CPU的利用率不高,说明资源没有充分利用,可以通过工具(如strace)查看应用程序阻塞在哪里,一般为磁盘,网络或应用程序的业务处理中存在休眠或信号等待,这些优化措施在后续其它章节描述。

l   如果CPU利用率高,通过优化软件硬件的配置参数来更好适配业务场景,减少CPU占用率,让整个系统有更多的CPU时间来处理业务。

我们也可以选择更好的硬件,根据CPU的能力配置合适的内存条,建议内存满通道配置,发挥内存最大带宽:一颗鲲鹏920处理器的内存通道数为8,两颗鲲鹏920处理器的内存通道数为16;建议选择高频率的内存条,提升内存带宽:鲲鹏920在1DPC配置时,支持的内存最高频率为2933MHz。

主要优化参数

优化项

优化项简介

默认值

生效范围

鲲鹏916

鲲鹏920

优化应用程序的NUMA配置

在NUMA架构下,CPU core访问临近的内存时访问延迟更低。将应用程序绑在一个NUMA节点,可减少因访问远端内存带来的性能下降。

默认不绑定核

立即生效

yes

yes

修改CPU预取开关

内存预取在数据集中场景下可以提前将要访问的数据读到CPU cache 中,提升性能;若数据不集中,导致预取命中率低,则浪费内存带宽。

on

重启生效

no

yes

调整定时器机制

nohz机制可减少不必要的时钟中断,减少CPU调度开销。

不同OS默认配置不同

Euler:nohz=off

重启生效

yes

yes

调整内存的页大小为64K

内存的页大小越大,TLB中每行管理的内存越多,TLB命中率就越高,从而减少内存访问次数。

不同OS默认配置不同:

4KB或64K

重新编译内核、更新内核后生效

yes

yes

优化应用程序的线程并发数

适当调整应用的线程并发数,使得充分利用多核能力和资源争抢之间达到平衡。

由应用本身决定

立即生效或重启生效(由应用决定)

yes

yes

1.2 常用性能监测工具

1.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、内存资源消耗。

l   CPU项:显示当前总的CPU时间使用分布。

  • us表示用户态程序占用的CPU时间百分比。

  • sy表示内核态程序所占用的CPU时间百分比。

  • wa表示等待IO等待占用的CPU时间百分比。

  • hi表示硬中断所占用的CPU时间百分比。

  • si表示软中断所占用的CPU时间百分比。

通过这些参数我们可以分析CPU时间的分布,是否有较多的IO等待。在执行完调优步骤后,我们也可以对CPU使用时间进行前后对比。如果在运行相同程序、业务情况下CPU使用时间降低,说明性能有提升。

l   KiB Mem:表示服务器的总内存大小以及使用情况。

l   KiB Swap:表示当前所使用的Swap空间的大小。Swap空间即当内存不足的时候,把一部分硬盘空间虚拟成内存使用。如果当前所使用的Swap空间大于0,可以考虑优化应用的内存占用或增加物理内存。

步骤 2      在top命令执行后按1,查看每个CPU core的使用情况。

通过该命令可以查看单个CPU core的使用情况,如果CPU占用集中在某几个CPU core上,可以结合业务分析触发原因,从而找到优化思路。

步骤 3      选中top命令的P选项,查看线程运行在哪些 CPU core上。

在top命令执行后按F,可以进入top命令管理界面。在该界面通过上下键移动光标到P选项,通过空格键选中后按Esc退出,即可显示出线程运行的CPU核。观察一段时间,若业务线程在不同NUMA节点内的CPU core上运行,则说明存在较多的跨NUMA访问,可通过NUMA绑核进行优化。

步骤 4      使用top -p $PID -H命令观察进程中每个线程的CPU资源使用。

“-p”后接的参数为待观察的进程ID。通过该命令可以找出消耗资源多的线程,随后可根据线程号分析线程中的热点函数、调用过程等情况

----结束

1.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则表示热点事件对应的函数名称。

通过热点函数,我们可以找到消耗资源较多的行为,从而有针对性的进行优化。

步骤 2      收集一段时间内的线程调用。

perf sched record命令用于记录一段时间内,进程的调用情况。“-p”后接进程号,“sleep”后接统计时长,单位为秒。收集到的信息自动存放在当前目录下,文件名为perf.data。

步骤 3      解析收集到的线程调度信息。

perf sched latency命令可以解析当前目录下的perf.data文件。“-s”表示进行排序,后接参数“max”表示按照最大延迟时间大小排序。

----结束

1.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访问内存。

步骤 2      通过numactl将进程绑定到指定CPU core。

通过 numactl -C 0-15 top 命令即是将进程“top”绑定到0~15 CPU core上执行。

可以通过numastat命令观察各个NUMA节点的状态。

l   numa_hit表示节点内CPU核访问本地内存的次数。

l   numa_miss表示节点内核访问其他节点内存的次数。跨节点的内存访问会存在高延迟从而降低性能,因此,numa_miss的值应当越低越好,如果过高,则应当考虑绑核。

----结束

1.3 优化方法

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

原理

通过1.1 鲲鹏处理器NUMA简介章节可以看到不同NUMA内的CPU core访问同一个位置的内存,性能不同。内存访问延时从高到低为:跨CPU > 跨NUMA不跨CPU > NUMA内

因此在应用程序运行时要尽可能的避免跨NUMA访问内存,我们可以通过设置线程的CPU亲和性来实现。

修改方式

l   网络可以通过如下方式绑定运行的CPU core,其中$cpuMask是16进制的数,最右边的bit表示core0;$irq为网卡队列中断号。

echo $cpuMask > /proc/irq/$irq/smp_affinity_list

l   通过numactl启动程序,如下面的启动命令表示启动test程序,只能在CPU core 28到core31运行(-C控制)。

numactl -C 28-31 ./test

l   在C/C++代码中通过sched_setaffinity函数来设置线程亲和性。

l   很多开源软件已经支持在自带的配置文件中修改线程的亲和性,例如nginx可以修改nginx.conf文件中的worker_cpu_affinity参数来设置nginx线程亲和性。

1.3.2 修改CPU的预取开关

原理

局部性原理分为时间局部性原理和空间局部性原理:

l   时间局部性原理(temporal locality):如果某个数据项被访问,那么在不久的将来它可能再次被访问。

l   空间局部性原理(spatial locality):如果某个数据项被访问,那么与其地址相邻的数据项可能很快也会被访问。

CPU将内存中的数据读到CPU的高速缓冲Cache时,会根据局部性原理,除了读取本次要访问的数据,还会预取本次数据的周边数据到Cache里面,如果预取的数据是下次要访问的数据,那么性能会提升,如果预取的数据不是下次要取的数据,那么会浪费内存带宽。

对于数据比较集中的场景,预取的命中率高,适合打开CPU预取,反之需要关闭CPU预取。目前发现speccpu和X265软件场景适合打开CPU预取,STREAM测试工具、Nginx和数据库场景需要关闭CPU预取。

修改方式

按照B 进入BIOS界面的步骤进入BIOS,然后在BIOS的如下位置设置CPU的预取开关。

1.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      重启服务器。

----结束

1.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

----结束

1.3.5 调整线程并发数

原理

程序从单线程变为多线程时,CPU和内存资源得到充分利用,性能得到提升。但是系统的性能并不会随着线程数的增长而线性提升,因为随着线程数量的增加,线程之间的调度、上下文切换、关键资源和锁的竞争也会带来很大开销。当资源的争抢比较严重时,甚至会导致性能明显降。下面数据为某业务场景下,不同并发线程数下的TPS,可以看到并发线程数达到128后,性能达到高峰,随后开始下降。我们需要针对不同的业务模型和使用场景做多组测试,找到适合本业务场景的最佳并发线程数。

修改方式

不同的软件有不同的配置,需要根据代码实现来修改,这里举例几个常用开源软件的修改方法:

  • MySql可以通过innodb_thread_concurrency设置工作线程的最大并发数。

  • Nginx可以通过worker_processes参数设置并发的进程个数。

作者:莱德汪汪队

鲲鹏性能优化十板斧(二)——CPU与内存子系统性能调优相关推荐

  1. 鲲鹏性能优化十板斧(三)——网络子系统性能调优

    1 网络子系统性能调优 3.1  调优简介 3.2  常用性能监测工具 3.3  优化方法 1.1 调优简介 调优思路 本章主要是围绕优化网卡性能和利用网卡的能力分担CPU的压力来提升性能.在高并发的 ...

  2. 【建议收藏】15755字,讲透MySQL性能优化(包含MySQL架构、存储引擎、调优工具、SQL、索引、建议等等)

    0. 目录 1)MySQL总体架构介绍 2)MySQL存储引擎调优 3)常用慢查询分析工具 4)如何定位不合理的SQL 5)SQL优化的一些建议 1 MySQL总体架构介绍 1.1 MySQL总体架构 ...

  3. 【建议收藏】15755 字,讲透 MySQL 性能优化(包含 MySQL 架构、存储引擎、调优工具、SQL、索引、建议等等)

    0. 目录 1)MySQL 总体架构介绍 2)MySQL 存储引擎调优 3)常用慢查询分析工具 4)如何定位不合理的 SQL 5)SQL 优化的一些建议 1 MySQL 总体架构介绍 1.1 MySQ ...

  4. numa节点_鲲鹏性能优化十板斧之前言 | 鲲鹏处理器NUMA简介与性能调优五步法

    鲲鹏处理器NUMA简介 随着现代社会信息化.智能化的飞速发展,越来越多的设备接入互联网.物联网.车联网,从而催生了庞大的计算需求.但是功耗墙问题以功耗和冷却两大限制极大的影响了单核算力的发展.为了满足 ...

  5. 鲲鹏性能优化十板斧(四)——磁盘IO子系统性能调优

    1.1 调优简介 调优思路 CPU的Cache.内存和磁盘之间的访问速度差异很大,当CPU计算所需要的数据并没有及时加载到内存或Cache中时,CPU将会浪费很多时间等待磁盘的读取.计算机系统通过ca ...

  6. 鲲鹏性能优化十板斧——鲲鹏处理器NUMA简介与性能调优五步法

    TaiShan特战队六月底成立,至今百日有余,恰逢1024程序员节,遂整理此文,献礼致敬!希望能为广大在鲲鹏处理器上开发软件.性能调优的程序员们,提供一点帮助.从今天开始,将陆续推出性能调优专题文章. ...

  7. Java编程性能调优-01|字符串性能优化不容小觑,百M内存轻松存储几十G数据

    一.字符串性能优化不容小觑,百M内存轻松存储几十G数据 一.String 对象是如何实现的? String str1= "abc"; String str2= new String ...

  8. Android Studio 性能优化工具 - Profiler、CPU Profiler、Memory Profiler、Netwrok Profiler、Evengy Profiler 详解

    关于性能优化的问题,可能一直有遇到,也一直在解决,但是在中小厂和自我要求不严格的场景下,我们很少去实实在在的做性能优化: 在性能优化中我们通常会通过自己的经验或工具来发现问题,本想着能短时间内搞定Pr ...

  9. Android性能优化典范(二)

    转自: http://www.csdn.net/article/2015-04-29/2824583-android-performance-patterns-season-2/1 摘要:Google ...

最新文章

  1. 谈几个初学者混淆不清的问题
  2. ASM(active shape models)算法介绍
  3. pthread_mutex_lock用法
  4. 日常生活小技巧 -- “Error: Encountered an improper argument”的解决方法
  5. Oracle Study之--Oracle 11g RAC设置归档路径错误案例
  6. [Object]面向对象编程(高程版)(二)原型模式
  7. springboot 不使用 thymeleaf_springboot 使用swagger 不显示basic-error-controller解决
  8. python def函数调用内容_基本的python,def函数和文本菜单的调用
  9. dirent struct_file属性读取 Struct dirent struct stat
  10. GXOI2019 题解
  11. TextStudio,调用CJK包不产生中文,以及Cannot find font gbk49 in map file的解决方案
  12. 站长统计工具区别:百度统计、51la统计系统和cnzz数据统计工具
  13. matplotlib之pyplot模块——填充两条曲线之间区域(fill_between、fill_betweenx)
  14. 如何解决Word只能用安全模式打开
  15. 【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法
  16. easyx的使用(3)
  17. Faker的妙用---造数
  18. LWN:在进程级别完成内核相同页面合并(KSM)控制!
  19. CTF-SMB信息泄露【简单易懂】
  20. 一个基础的反射型xss))

热门文章

  1. 网格布局(Grid Layout)
  2. Flask之Flask实例有哪些参数
  3. Servlet简单实现请求分发(类thinkphp5)
  4. 数据结构与算法(刺猬书)读书笔记----目录
  5. AutoCAD2004启动时出现fail to get CommcntrController的怎么办
  6. [WCF]NetTcpBinding在IIS中使用的详细配置方法
  7. MIX08,迎来Silverlight2的新时代
  8. CCF201912-1 报数
  9. 国庆活动延长三天!快来领取你的数据技术嘉年华门票!
  10. 今晚8点,Oracle ACE男神Roger详解Oracle中为什么没有double write?