------------恢复内容开始------------
perf工具
1、查找耗时点、cache-misses、L1-dcache-load-misses
perf top -C x
perf record -g -e cpu-clock -F 99 -p xxx
perf report --- 函数、汇编
perf record -e L1-dcache-load-misses,cpu-clock -C 3 sleep 10
perf report --stdio | grep XFWD
最近参与了acl性能优化的方面的工作,目前优化过程接近尾声,过程中走了不少弯路,当然也学习到了很多性能优化的方法,现在做下总结。
大多说优化基本都是对软件的优化,所以这里不谈硬件优化。
一般软件涉及到性能问题,首先要确认性能点出在哪里?我们可以使用perf工具来跟踪系统的性能,也可以来跟踪某个进程的性能耗时点,是一个非常棒的性能分析工具。这里可以首先定位到哪个函数耗时,进而定位到业务流程上。
优化的过程有这么几个,首先是对算法的优化,也就是根据业务逻辑功能来分析现有算法是否最优,这么多年的经验来看,无非是CRUD,既然涉及到性能,一定是一个动态的过程,根据上面的函数就可以知道这个函数时发生在哪个阶段。比如发生在查找阶段,那么如果查找的数据结构是链表,改成hash或者树结构那效率肯定明显提升,具体的hash种类及树结构的种类下面会详细介绍。其次才是代码实现细节的优化,这个时候还可以使用perf来看下耗时的原因是什?那影响代码性能的点有这么几个:首当其冲的是缓存cache-miss、就是要访问的数据不再cache里,要到内存或者磁盘上获取。这里的cache理论知识不再这里讲解,本章节只对性能优化的步骤方法进行总体的阐述。那么如何降低cachemiss,可以到下面看详细过程。有一点要重视,cachemiss不可能完全消除,不要太固执。其次可以在内存、耦合、开栈、指令、寄存器、延迟计算、提前计算等方面
优化角度:架构、算法、代码。软件&硬件。
这里不讨论硬件优化,以及架构优化,因为这个都是系统级别的,不是可以轻易优化的。
了解业务 ------- 优化算法 或 设计新算法 ---------- 优化代码
首先要对业务有非常通透的理解,因为大多数代码首次开发或者架构设计的时候受项目进度约束,并非最完美的,了解了业务,同时明确目前的代码实现,
这样就可以找出当前的代码存在冗余的部分,可以除去不必要的处理,或者合并部分处理过程。甚至设计新的算法。算法确认最优后,其次才能对代码细节做优化。
算法优化:线性表-----链表------哈希-----树
栈、队列:这两个一般是功能型的结构,不涉及性能。
线性表:定义的数组、开辟的连续内存
链表:指针、向量
哈希:bihash、多级hash
树:二叉树、
平衡二叉树:搜索性能好
红黑树: 插入删除动态调整的性能好
以上适用于数据较小,完全可以放在内存中。
=================================================
B树:多叉树
B+tree:数据都在叶子结点,平衡查找速度
B*tree:可指向兄弟节点,减少分裂。
以上适用于数据库等数据量较大,需要放在磁盘上。
=================================================
tire树:每个节点保存一个元素,空间换时间
radix树:相比于trie树,压缩了中间节点,不止保存一个元素。
适用于字符查找,或者有规律的编码结果进行快速查找
=================================================
代码优化方法:
内存角度:大页表(TLB、大页内存):访问内存,要查页表,加速查表。
缓存角度:cache优化(i-cache、d-cache、对齐)、数据预取(连续内存、适度预取)
耦合角度:高内聚低耦合(相关代码放在一起)、减少冗余代码
开栈角度:减少调用层次 、inline、宏构造函数、
指令角度:循环展开(指令预取相关)、分支预测(likely)
其他:寄存器参数、延迟计算、提前计算
拓展:多核、多线程、共享数据、读写分离、异步、并发、上下文切换、内存池、
问:为了减少函数调用层次,减少开栈时间,而把一个函数写的较大,
------------恢复内容结束------------