知道这些性能优化手段,工资起码提升一倍

共 6474字,需浏览 13分钟

 ·

2021-12-22 22:29

1.什么是性能?性能指标有哪些?

计算机的性能,其实和我们干体力劳动很像,好比是我们要搬东西。对于计算机的性能,我们需要有个标准来衡量。这个标准中主要有两个指标。第一个是响应时间(Response time)或者叫执行时间(Execution time)。想要提升响应时间这个性能指标,你可以理解为让计算机“跑得更快”

        第二个是吞吐率(Throughput)或者带宽(Bandwidth),想要提升这个指标,你可以理解为让计算机“搬得更多”。

所以说,响应时间指的就是,我们执行一个程序,到底需要花多少时间。花的时间越少, 自然性能就越好。而吞吐率是指我们在一定的时间范围内,到底能处理多少事情。这里的“事情”,在计算机里就是处理的数据或者执行的程序指令。和搬东西来做对比,如果我们的响应时间短,跑得快,我们可以来回多跑几趟多搬几趟。所以说,缩短程序的响应时间,一般来说都会提升吞吐率。除了缩短响应时间,我们还有别的方法吗?当然有,比如说,我们还可以多找几个人一起来搬,这就类似现代的服务器都是 8 核、16 核的。人多力量大,同时处理数据,在单位时间内就可以处理更多数据,吞吐率自然也就上去了。提升吞吐率的办法有很多。大部分时候,我们只要多加一些机器,多堆一些硬件就好了。但是响应时间的提升却没有那么容易,因为 CPU 的性能提升其实在 10 年前就处于“挤牙膏”的状态了,所以我们得慎重地来分析对待。

下面我们具体来看。我们一般把性能,定义成响应时间的倒数,也就是:性能 = 1/ 响应时间这样一来,响应时间越短,性能的数值就越大。同样一个程序,在 Intel 最新的 CPU Coffee Lake 上,只需要 30s 就能运行完成,而在 5 年前 CPU Sandy Bridge 上,需要 1min 才能完成。那么我们自然可以算出来,Coffee Lake 的性能是 1/30,Sandy Bridge 的性能是 1/60,两个的性能比为 2。于是,我们就可以说,Coffee Lake 的性能是 Sandy Bridge 的 2 倍。过去几年流行的手机跑分软件,就是把多个预设好的程序在手机上运行,然后根据运行需要的时间,算出一个分数来给出手机的性能评估。而在业界,各大 CPU 和服务器厂商组织了一个叫 SPEC(Standard Performance Evaluation Corporation)的第三方机构,专门用来指定各种“跑分”的规则。

2.如果性能不达标怎么办?

使用Profiler性能分析器首先确定性能瓶颈出现在哪里,定位性能问题出现的根本原因,按照具体原因去做优化。

通常来说,性能问题大致出现在两个方面:

1.细节不够好(资源问题、插件问题、代码写法问题)

2.结构不够好(框架问题、底层API问题)

细节问题解决成本低,可以独立调整,对其他部分影响小,可以批量解决。

结构问题解决成本高,牵一发动全身,对其他部分影响大,需要大修、大测。

由于游戏整体是由各个细节组成的,所以当细节做的不够好时,整体也会显现出问题。

反之当结构不够好时,细节即使做的很好,游戏整体表现出的性能也不会太好,两者是相辅相成的。

我的建议是:用严格认真的态度控制细节,用丰富的经验积累出可靠的结构。

前者靠态度,后者靠经验。当我们经验不多时,应该依靠态度严控细节,当我们经验足够时,两方面都要兼顾。



调优策略:追求基于满足诉求的精度条件下的性能提升。但是,如果性能已经达到无法接受的程度,那么就先解决性能,处理到可接受为止。
精度调优过程中导致性能恶化,或者性能调优过程中导致精度恶化,记住两点:
1、千万不要兜圈子,不要精度差了搞精度,性能差了又搞性能。
2、有阶段成果后,后续的尝试和修改一定要分步骤执行,做好记录

3.训练服务器的演示及简介

Atlas 800 训练服务器(型号9000)是基于华为鲲鹏920+昇腾910处理器的AI训练服务器,实现完全自主可控,广泛应用于深度学习模型开发和AI训练服务场景。该服务器面向公有云、互联网、运营商、政府、交通、金融、高校、电力等领域,具有高计算密度、高能效比、高网络带宽、易扩展、易管理等优点,支持单机和整机柜销售,支持风冷和液冷应用,满足企业机房部署和大规模数据中心集群部署。

计算产品3D展示 (huawei.com)

大家可以使用上面的地址进行3D模型预览及展示,可以看这个服务器的构造及拆解组件,体验感十足。

这个性能分析在昇腾全栈AI软硬件平台主要体现在标记的异构计算架构部分,释放硬件的算力。

4.训练执行的过程是什么样的?

OBS资源图里有很多细分的图表,其实不需要全部记住,因为每个指标的变化都不是独立的,是与其他指标关联的

1、每秒点击数

每秒点击数(Hits per Second)统计的是运行场景过程中,虚拟用户每秒向Web服务器提交的HTTP请求数。该指标经常与其他指标结合进行分析

2、吞吐量

吞吐量(Throughput)统计场景运行过程中服务器的每秒吞吐量,单位是字节,表示虚拟用户在任何给定的每一秒内,从服务器获得的数据量。通过该指标可以看出服务器在流量方面的处理能力以及是否存在瓶颈,正常情况下,吞吐量与TPS图的变化基本一致。若压力增大时,吞吐量的曲线增加到一定程度后变化缓慢,甚至平坦,则很可能是网络出现带宽瓶颈。不论是吞吐量,还是TPS都非常不稳定,尤其是TPS,通过率比较低

3、HTTP状态码概要

HTTP状态码概要(HTTP Status Code Summary)统计场景运行过程中,从Web服务器返回的HTTP状态代码数,返回的都是200状态码,说明在HTTP返回层面上是成功的

4、每秒HTTP响应数

每秒HTTP响应数(HTTP Responses per Second)统计运行场景过程中,每秒从Web服务器返回的不同HTTP状态码的数量。一般和每秒点击量相同,如果服务器的响应数小于点击量,那么说明服务器无法应答,超过负载的链接请求

5、连接数

连接数(Connections)统计场景运行过程中,每个时间点打开的TCP/IP连接数。例如,当连接数dadao 稳定状态而事务响应时间迅速增大时,添加连接可以使用性能得到极大提高

6、每秒连接数

每秒连接数(Connections Per Second)统计新建的连接数和关闭的连接数,方便了解每秒对服务器产生连接的数量。同时连接数越多,说明服务器的连接池越大,当连接数随着负载上升而停止时,说明系统的连接池已满,通常这个时候服务器会返回504错误

7、每秒重试次数

每秒重试次数图显示在场景运行的每一秒内,服务器尝试的连接次数。在下列情况下将重试服务器连接

初始连接未经授权

要求代理服务器身份验证

服务器关闭了初始连接

初始连接无法连接到服务器

服务器最初无法解析负载生成器的IP地址

8、每秒SSL连接数

每秒SSL连接数图显示在场景运行的每一秒内,重新使用的SSL连接数。当对安全服务器打开TCP/IP连接后,浏览器打开SSL连接。因为新建SSL连接需要消耗大量的资源,所以应该尽量减少打开新的SSL连接。建立新SSL连接后,应该重复使用该连接。每个虚拟用户的新SSL连接数不应该超过一个。理想情况下,每秒都应该只有很少量的新TCP/IP和SSL连接.

5.将整网训练阶段进行分段,分析性能影响

1).数据读取阶段:主要影响在HOST侧

2).数据预处理阶段:HOST和DEVICE都可能涉及

3).训练后处理阶段:HOST和DEVICE都可能涉及

相关文档Log/Summary_昇腾CANN社区版(5.0.3 alpha 001)(训练)_TensorFlow模型迁移和训练_手工迁移和训练_更多特性_华为云 (huaweicloud.com)

4).训练执行阶段:主要影响在DEVICE侧

6.打开Profiling前,确认当前源码状态(确认当前源码处在手工迁移后的状态)

原始的代码:
sess=tf.Session()
自动迁移后的代码:
sess = tf.Session(config=npu_config_proto())
手工迁移后的代码:
config = tf.ConfigProto()
custom_op = config.graph_options.rewrite_options.custom_optimizers.add()
custom_op.name = "NpuOptimizer"
config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
config.graph_options.rewrite_options.memory_optimization = RewriterConfig.OFF
sess = tf.Session(config=config)

设置Profiling开关,打开Profiling

手工迁移后的代码:
config = tf.ConfigProto()
custom_op = config.graph_options.rewrite_options.custom_optimizers.add()
custom_op.name = "NpuOptimizer"
config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
config.graph_options.rewrite_options.memory_optimization = RewriterConfig.OFF
sess = tf.Session(config=config)
设置profiling后的代码:
config = tf.ConfigProto()
custom_op = config.graph_options.rewrite_options.custom_optimizers.add()
custom_op.name = "NpuOptimizer"
custom_op.parameter_map["profiling_mode"].b = True
custom_op.parameter_map["profiling_options"].s =
tf.compat.as_bytes('{"output":"/mypath/output","task_trace":"on","training_trace":"on","aicpu":"on","fp_point":"","bp_point":""}')
config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
config.graph_options.rewrite_options.memory_optimization = RewriterConfig.OFF
sess = tf.Session(config=config)

操作手册请参考功能介绍_昇腾CANN社区版(5.0.3 alpha 001)(训练)_开发辅助工具_Profiling工具使用指南_概述_华为云 (huaweicloud.com)

7.总结:遇到性能问题时,推荐的debug顺序和手段是什么样的?

core dump的调试

首先说一下core的解决思路,主要是如下几点:

  1. gdb及debug log定位,发现作用不大。

  2. 如何重现bug?

  3. 构造高并发压力测试系统。

  4. 构造稳定的异常请求。

使用TC(traffic control)工具来构造弱网络环境,但是转念一想,弱网络环境导致的结果是什么?显然是网络请求的各种异常啊,所以还不如直接构造各种异常请求来复现问题。于是准备构造测试工具和环境,需要满足两个条件:

  1. 并发性能强,能够同时发送数万甚至数十万级以上qps。

  2. 请求需要一定概率的异常。特别是TCP握手及SSL握手阶段,需要异常中止。

WRK压力测试工具

由于高并发流量时才可能出core,所以首先就需要找一个性能强大的压测工具。
WRK是一款非常优秀的开源HTTP压力测试工具,采用多线程 + 异步事件驱动的框架,其中事件机制使用了redis的ae事件框架,协议解析使用了nginx的相关代码。
相比ab(apache bench)等传统压力测试工具的优点就是性能好,基本上单台机器发送几百万pqs,打满网卡都没有问题。
wrk的缺点就是只支持HTTP类协议,不支持其他协议类测试,比如protobuf,另外数据显示也不是很方便。

nginx的测试用法:wrk -t500 -c2000 -d30s https://127.0.0.1:8443/index.html

linux世界有许多非常好用的性能分析工具,我挑选几款最常用的简单介绍下:
1. [perf](Perf Wiki)应该是最全面最方便的一个性能检测工具。由linux内核携带并且同步更新,基本能满足日常使用。**推荐大家使用**。
2. oprofile,我觉得是一个较过时的性能检测工具了,基本被perf取代,命令使用起来也不太方便。比如opcontrol --no-vmlinux , opcontrol --init等命令启动,然后是opcontrol --start, opcontrol --dump, opcontrol -h停止,opreport查看结果等,一大串命令和参数。有时候使用还容易忘记初始化,数据就是空的。
3. gprof主要是针对应用层程序的性能分析工具,缺点是需要重新编译程序,而且对程序性能有一些影响。不支持内核层面的一些统计,优点就是应用层的函数性能统计比较精细,接近我们对日常性能的理解,比如各个函数时间的运行时间,,函数的调用次数等,很人性易读。
4. systemtap 其实是一个运行时程序或者系统信息采集框架,主要用于动态追踪,当然也能用做性能分析,功能最强大,同时使用也相对复杂。不是一个简单的工具,可以说是一门动态追踪语言。如果程序出现非常麻烦的性能问题时,推荐使用 systemtap。

这里再多介绍一下perf命令,tlinux系统上默认都有安装,比如通过perf top就能列举出当前系统或者进程的热点事件,函数的排序。
perf record能够纪录和保存系统或者进程的性能事件,用于后面的分析,比如火焰图。

  1. 调试BUG是一次非常难得的学习机会,不要把它看成是负担。不管是线上还是线下,能够主动地,高效地追查BUG特别是有难度的BUG,对自己来说一次非常宝贵的学习机会。面对这么好的学习机会,自然要充满热情,要如饥似渴,回首一看,如果不是因为这个BUG,我也不会对一些工具有更深入地了解和使用,也就不会有这篇文档的产生。

  2. 不管什么样的BUG,随着时间的推移,肯定是能够解决的。这样想想,其实会轻松很多,特别是接手新项目,改造复杂工程时,由于对代码,对业务一开始并不是很熟悉,需要一个过渡期。但关键是,你要把这些问题放在心上。白天上班有很多事情干扰,上下班路上,晚上睡觉前,大脑反而会更加清醒,思路也会更加清晰。特别是白天上班时容易思维定势,陷入一个长时间的误区,在那里调试了半天,结果大脑一片混沌。睡觉前或者上下班路上一个人时,反而能想出一些新的思路和办法。

  3. 开放讨论。遇到问题不要不好意思,不管多简单,多低级,只要这个问题不是你google一下就能得到的结论,大胆地,认真地和组内同事讨论。方法总比困难多!



好啦,本期内容孙叫兽就分享到这里,我们下期见!


浏览 42
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报