本篇先介绍了程序优化的整体流程,而后对每个步骤的注意事项进行详细说明。
整体流程
步骤细究
确定目标
性能指标的选择。在上一篇文章中我们介绍了多个性能指标,根据性能指标的不同,程序的瓶颈位置也不同,优化的策略、效果也不同。
对最优状态的估计。确定目标之前应该先使用理论工具(如上一篇介绍的Amdahl定律、Gustafson定律,当然还有别的工具)估计出最优的状态,实际的优化工作只能接近该状态。
测量程序性能指标
测试用例问题
测试用例既具有随机性又具有可复现性,如果测试用例比较平凡、比较特殊,那么无法代表一般情况,优化过程对实际应用并不一定有效(是不是有点类似于人工智能中的过拟合?),如果测试的用例完全不可复现,那么就无法精确比较优化前后的效果。可以使用固定随机数种子等方式来解决该问题。
测试的时间既不能太长又不能太短,如果测试的时间太长,会占用大量的优化时间,耽误优化进度,如果测试的时间太短,主要的性能问题潜藏在多种正常开销之中无法充分显露。
如何测量
详见下一章《四、程序性能的测量和分析》(已有或将有)。
分析查找瓶颈
这个阶段非常困难并需要经验,好在我们有很多的工具和策略来得到这一点,详见下一章《四、程序性能的测量和分析》(已有或将有)。
针对性修改程序
程序正确性。修改程序首先要保证程序的正确性,否则优化将失去意义。对于等价性优化(代码段输入输出与优化前相同)只要对比二者的输入输出即可,对于非等价性优化(使用了不同的策略、不同的理论),就要利用各种测试用例来检验程序的正确性了。为了进一步保证这一点,最好使用代码仓库等工具保存好每一次优化的版本。
程序可读性。 在程序优化过程中,通常需要对代码进行重构或者改进。可读性高的代码更容易被识别出潜在的性能问题或者优化点,并且更容易被改进和优化。此外,重构过程中也能够更好地保持代码的结构和逻辑清晰,避免引入新的问题。当程序出现错误时,可读性高的代码能够帮助开发人员更快地定位问题所在。清晰易懂的代码使得调试过程更加高效,减少了排错的时间和成本。
专栏安排(已有,或将有)
一、程序性能优化的意义
五、程序编写时的优化(上):算法优化、数据结构优化、函数优化
七、编译与运行时的优化(上):编译器结构、编译选项、编译优化
七、编译与运行时的优化(下):数学库优化、运行时的优化
八、系统配置的优化
九、单核优化
十、OpenMP程序优化
十一、MPI程序优化
十二、…
如有不足之处,敬请批评指正
更欢迎在评论区留下你的见解,你的方法,如果有效我会增加在文章中,并@你。