58龙哥教你“如何做系统性能优化”(纯干货)

简介: 需要在性能优化和上述的几个要求之间做出tradeoff,不能一意孤行。

image.png

如何做系统性能优化

性能优化的目标是什么?不外乎两个:
时间性能:减小系统执行的时间
空间性能:减小系统占用的空间

一、代码优化

做代码优化前,先了解下硬件Cache:
(1)Cache Level:通常来说L1、L2的Cache集成在CPU里,L3的Cache放在CPU外;
(2)Cache Size:它决定你能把多少东西放到Cache里,有Size就有竞争,就有替换,才有所谓优化的空间;
(3)Cache Type:I-Cache(指令),D-Cache(数据),TLB(MMU的Cache);

代码层次的优化主要从以下两个角度考虑问题:
(1)I-Cache优化:精简code path,简化调用关系,减少冗余代码等等;
(2)D-Cache优化:减少D-Cache的miss数量,增加有效数据访问。

以下是一些技巧,可供参考:
(1)Code adjacency(把相关代码放在一起)
这里有两层含义:一是相关源文件要放在一起;二是相关函数在object文件里面,也应该相邻。
这样,可执行文件被夹在到内存里时,函数位置也是相邻的,同事还符合模块化编程的要求:高内聚,低耦合。
(2)Cache line alignment(cache对齐)
对齐Cache以减少潜在的一次读写,但这可能意味着内存的浪费,需要从空间和时间两方面衡量。
(3)Branch prediction(分支预测)
如果能预测那段代码有更高的执行概率,就能减少跳转次数(调整if和else的顺序?)。
(4)Data prefetch(数据预取)
由CPU自动完成。
(5)Register parameters(寄存器参数)
(6)Lazy computation(延时计算)
最近不用的变量,不要急着去初始化(意味着可能执行复杂的构造),如果某个分支跳出了函数,这些动作就浪费了。
COW(copy-on-write)就是一种延时计算的技术。
(7)Early computation(提前计算)
有些变量,计算一次就够了,任何加减乘除都会消耗CPU指令,尽量使用常数,而不是246060来表示一天的秒数。
(8)Inline(内联函数)
(9)Macro(宏定义)
(10)Allocation on stack(局部变量)
避免在栈上申请大数组,其初始化和销毁的代价很高。
(11)Per-cpu data structure(非共享数据结构)
避免共享量的锁,在thread local里,多核情况下使用局部变量会带来好处。
(12)Reduce call path or call trace(减少函数调用层次)
(13)Read&write split(读写分离)
(14)Recude duplicated code(减少冗余代码)

其中,(1)(6)(7)(8)(9)(10)(11)(12)(14)这些优化方式最为常见。

二、工具优化

“工欲善其事,必先利其器”,如果没有工具的支持,性能优化难以实施,谁也不知道哪些地方是严重影响性能的主要矛盾。
使用性能优化的工具,需要考虑以下问题:
(1)使用工具是否需要重新执行编译?
(2)工具本身对测量结果的影响:工具对性能的影响必须在一个可接受的范围以内。

工具能解决的问题:
(1)建立性能基线,以作对比;
(2)帮助定位性能瓶颈;
(3)帮助验证优化方案;

性能测试工具一般由这么几种:
(1)收集CPU的性能计数;
(2)利用编译器的功能,在函数入口和出口加回调函数;
(3)在代码中加入时间测量点。

在Linux下,通常会用到的有:

(1)Oprofile

它已经加入Linux内核代码库,但通常需要重新编译内核,参考如下
http://oprofile.sourceforge.net/news/
http://people.redhat.com/wcohen/Oprofile.pdf

(2)KFT and Gprof

KFT是kernel的一个patch,只对kernel有效;Gprof是gcc里面的一个工具,只对用户空间的程序有效。这两个工具都需要重新编译代码,它们都用到了gcc里面的finstrument-functions选项。编译时会在函数入口,出口加回调函数,而且inline函数也会改成非inline的。它的工作原理可以参考:
http://blog.linux.org.tw/~jserv/archives/001870.html
http://blog.linux.org.tw/~jserv/archives/001723.html
http://elinux.org/Kernel_Function_Trace
http://www.network-theory.co.uk/docs/gccintro/gccintro_80.html

三、系统优化

从系统层面去优化系统往往有更为明显的效果,优化之前,可以思考,是否能够通过扩展系统来达到提高性能的目的:
(1)Scale up:使用更强的硬件;
(2)Scale out:使用更多的组件;

如果升级硬件的方法就能解决问题,为什么还要使用修改代码,调整架构这样大风险的举措呢?(需要考虑成本)
以下是一些常用的系统优化的方法:

(1)Cache

Cache干什么?保存已经执行过的结果。
Cache为什么有效?避免已计算过的开销,获取更快的访问。
Cache的难点在哪里?一是快速匹配;二是Cache容量有效,需要较好的替换策略;
Cache在哪些情况下有效?时间局部性。即当前计算的结果,后续有可能使用到,如果没有时间局部性,反而对架构有害。

(2)Lazy Computing

理念就是,不要做多余的事情,最常见的例子就是COW(copy-on-write):
http://en.wikipedia.org/wiki/Copy-on-write
COW干什么?写时复制。
COW为什么有效?节省内存复制时间,均匀内存分配时间。
COW的难点在哪里?一是引用计数的使用;二是确认哪些内存是可以共享的。

(3)read ahead/pre-fetch预读

http://en.wikipedia.org/wiki/Readahead
预读干什么?提前准备所需要的数据。
预读为什么有效?减少等待内存的时间,相当于把多个操作集合成一个。
预读在哪些情况下有效?空间局部性。

(4)Asynchronous异步

http://en.wikipedia.org/wiki/Asynchronous_I/O
异步干什么?异步是一种通信方式,请求与应答分离。
异步为什么有效?消除等待时间。
异步的难点是什么?如何实现分布式状态机,如何使用回调,使异步时间到达后继续执行。
异步在哪些情况下有效?状态之间不能有强依赖关系。

(5)Polling轮询

http://en.wikipedia.org/wiki/Polling_(computer_science)

(6)Static memory pool(内存池)

http://en.wikipedia.org/wiki/Static_memory_allocation
内存池干什么?提前分配内存以获取更好的性能,只是适应性可能会降低,并可能造成内存浪费。
内存池为什么有效?避免重复内存申请、释放开销。
内存池的难点是什么?分配多大的内存池,如何避免浪费都是需要考虑的问题。
内存池在哪些情况下有效?一是固定大小的内存需求,二是快速的分配与释放需求。

四、总结

性能优化只是系统的一个方面,它可能会和系统的其他要求有冲突,比如
可读性:性能优化不能影响可读性,谁愿意维护不怎么漂亮的代码;
模块化:性能优化往往需要打破模块的边界,想想这是否值得;
可移植:隔离硬件相关的代码,尽量使用统一的API;
可维护:许多性能优化的技巧,会导致后来维护代码的人崩溃;

需要在性能优化和上述的几个要求之间做出tradeoff,不能一意孤行。

目录
相关文章
|
4月前
|
边缘计算 网络协议 安全
AIWCLOUD:基于BGP Anycast的免备案CDN路由优化实践
AIWCLOUD免备案CDN技术:通过BGP Anycast智能调度、私有隧道回源、内核级TCP调优(BBR/TFO/InitCWND)及源站隐身等创新,突破ICP备案限制,在合规前提下实现未备案域名的大陆高速稳定访问。(239字)
395 1
|
11月前
|
人工智能 IDE 编译器
如何用给各种IDE配置R语言环境
R语言虽无Python式虚拟环境,但通过Conda管理或多项目隔离方案(如自定义.libPaths或使用renv工具),可实现包依赖独立、版本锁定与环境复现,支持跨平台迁移与协作,真正做到“一次配置,永久可用”。推荐renv+RStudio组合,高效管理项目环境。
1024 6
|
6月前
|
小程序 前端开发 API
高端家政平台源码​|支持多端家政小程序源码接入+APP一站式部署
本文详解一套支持微信、支付宝、抖音等多端小程序无缝接入的高端家政平台源码,采用“云原生微服务+Uni-app跨端框架”架构,实现一次开发、多端部署。涵盖登录统一、支付适配、地图集成、消息推送等核心模块的多端落地策略,助力企业低成本触达全渠道用户。
|
存储 人工智能 数据可视化
从需求到闭环:个人任务管理看板工具如何提升开发者每日效率?
现代人常陷入任务堆积、效率低下的困境。看板工具通过可视化任务状态、优先级排序和进度跟踪,为个人任务管理提供了高效解决方案。本文系统介绍了看板工具的核心原理(任务卡片、工作流)、主要功能(标签管理、多端同步)及主流产品对比(板栗看板、Notion等),并给出实用技巧:结合番茄工作法、定期复盘、避免任务堆积等。文章指出,看板不仅是工具,更是一种优化时间管理的思维方式,能有效减轻焦虑、提升生产力,适合学生、职场人士等各类人群。随着AI技术的发展,未来看板工具将更智能化,成为个人效率管理的得力助手。
477 0
|
存储 缓存 NoSQL
除了File存储方式,还有哪些适合类Web开发范式的状态持久化方法?
除了File存储方式,还有哪些适合类Web开发范式的状态持久化方法?
|
数据采集 数据可视化 安全
基于python大数据的天气可视化分析预测系统
本研究探讨基于Python的天气预报数据可视化系统,旨在提升天气数据获取、分析与展示的效率与准确性。通过网络爬虫技术快速抓取实时天气数据,并运用数据可视化技术直观呈现天气变化趋势,为公众出行、农业生产及灾害预警提供科学支持,具有重要的现实意义与应用价值。
都8102年了,还用fastq-dump,快换fasterq-dump吧
之前写过一篇文章Fastq-dump: 一个神奇的软件, 详细介绍了fastq-dump的用法。 虽然fastq-dump参数很多,而且一直被吐槽参数说明写的太差,但是如果真的要用起来其实也就是一行代码 fastq-dump --gzip --split-3 --defline-qual '+' --defline-seq '@$ac-$si/$ri' SRRXXXXX| SRRXXXX.sra # 加上--gzip后需要时间进行文件压缩 当然除了参数问题,还有一个让人诟病的地方就是他只能单个线程,所以速度特别的慢。
5846 0
都8102年了,还用fastq-dump,快换fasterq-dump吧
|
算法 数据挖掘 API
《拼多多 API 助力,拼多多店铺商品好评率快速提升》
本文介绍如何利用拼多多开放平台API自动化管理商品评论,提升店铺好评率。通过获取评论数据、自动回复差评、数据分析与批量操作,商家可高效优化好评率,提升店铺曝光与转化。内容涵盖API使用步骤、优势及注意事项,助力商家实现数据驱动的精准运营,提升顾客满意度。
|
编解码 IDE KVM
Happy coding,明基RD280U使用分享
最近尝试了明基的专业编程显示器 `RD280U`,28寸4K分辨率,3:2屏幕比例,适合编程。支持硬件级防蓝光、抗反射面板,接口丰富,支持KVM。自动亮度调节、编码模式和软件辅助功能,使其在编程体验上表现出色。如果你对专业编程显示器有需求,这无疑是一个不错的选择。
1252 12
|
数据挖掘 BI
数字化产科管理平台解决方案
数字化产科管理平台旨在解决产科应用痛点,通过建设孕产保健信息系统,实现保健、临床及上级管理系统间的互联互通,打造一体化服务模式。平台涵盖门诊、住院、统计三大模块,实现从建档到产后管理的全生命周期管理,提升高危管理效率,减少人工文书工作,优化资源配置,并提供精准的统计分析功能,助力科研与业务发展。
577 0
数字化产科管理平台解决方案