C++ 性能白皮书
引言
性能优化是 C++ 开发中的重要课题。本文将从硬件架构到具体代码实现,系统地介绍 C++ 性能优化的关键技术和最佳实践,帮助开发者构建高性能的 C++ 应用程序。
最近看完了《C++ 性能白皮书》,这本书列出了一些性能优化的思路,不过只是一些指引,没有讲具体细节,我整理出了其中的关键点分享给大家:
硬件篇
作为一个程序员,想要性能优化,最好要了解些硬件,特别是 CPU 架构的一些知识点:
- 流水线
- 分支预测
- 寄存器重命名
- 数据预取
- 指令重排和乱序执行
- 同时多线程(超线程)
- 数据并行 SIMD 单指令多数据
还要了解 CPU 的特点:
- 一个处理器上,多条指令可能同时执行
- 一个处理器上,代码的执行结果会和程序员可观察到的顺序一致,但其他处理器观察到的执行结果可能不是一个顺序
- 顺序、无跳转的代码性能最高
- 相邻且对齐的数据访问性能最高
内存方向的优化:
- 金字塔图需要了解

还需要了解 CPU 多级缓存和关键跨度的概念,这块可以看这篇文章。
要了解基本工具:
- 编译器:MSVC GCC clang
- 不同级别的优化:O1 O2 O3 以及他们的主要区别
需要知道性能分析指导下的优化:PGO profile-guided optimization
也就是利用程序运行的 profiling 数据,指导编译器进一步优化。多测试,找到程序热点,根据数据针对性优化。
还有链接期优化:link-time optimization LTO
LTO 可以:
- 跨翻译单元的函数内联
- 跨翻译单元的程序整体优化
- 死代码消除
做性能优化,需要了解性能测试的阿姆达尔定律,80-20 原则,20% 的代码决定了 80% 的结果,如果对 20% 以外的代码进行优化,性价比太低,性能测试的意义就在于此:
- 找出代码中性能开销最大的部分
- 测量代码优化之后的实际收益
需要熟练使用性能采样工具:
- Windows 中 Visual Studio 有自带的性能分析工具
- Linux 有 Perf 或者 gperftools
C++篇
关于 C++ 语言层面的优化,可以在下面这些方向做优化:
- 优先栈内存,次之堆内存
- 巧妙使用 RAII 管理资源
- 移动语义虽然不好理解,但也可以巧妙使用移动语义减少对象的非必要拷贝
- 模板和泛型技巧华而不实,给开发标准库的人使用还好,而且调试难度也较高,我们普通业务开发者只需要做到能看懂即可(个人见解)
- 异常是可以考虑使用的,可以看看 ISO C++ 网站和 C++ 核心指南 62,异常会导致程序的二进制体积有膨胀(5%-15%),异常不能代替所有的错误码,因为异常 catch 会使得程序性能下降。作者认为:使用异常对于大部分 C++ 项目仍然适用,不使用异常的麻烦大于好处,除非真因为二进制文件和实时性方面的原因需要禁用异常。
- 字符串默认类型时 const char[],传参时会退化成 const char*,创建全局字符串最好使用 const char[]
- 标准库容器的方法至少提供了基本异常安全保证:要了解强异常安全保证和无异常保证。
- vector 的移动构造函数标记为 noexcept 才会使用移动构造,移动构造函数需要标记为 noexcept,如果没有标记,代码性能可能会有较大的负面影响。
- shared_ptr 构造优先使用 make_shared
- 了解 function,function 用作回调很方便,支持类型擦除,它还有个好处,可以用来存储带状态的函数对象,不像 C 语言那样需要个 void*存储状态。但需要了解它的开销,貌似 48 个字节是个坎。
- 堆内存管理:可以了解下 jemalloc mimalloc tcmalloc
- 输入输出流可以考虑使用
ios_base::sync_with_stdio(false)关闭同步,性能会提升,也最好使用 \n 取代 endl,免得频繁刷新缓冲区。可考虑使用 fmt - 并发
- 需要了解内存序的概念
- 一些优质的多生产者多消费者并发队列
- moodycamed::ConcurrentQueue
- atomic_queue
- Folly 中 MPMCQueue
- 标准库也有些并行策略:
- execution::seq 序列执行,不可并行
- par:可并行化
- par_unseq:可并行化 向量化
- unseq:可向量化
通用方法篇
通用优化方法
- 优化原则:不要执行不必要的代码
- 循环优化,尽量减少临时对象的创建
- 结构体设计时最好做到对齐
- 尽量顺序访问数据,矩阵乘法可以很好的印证 CPU Cache 的作用,再考虑添加 -O3 -march=native 开启 SIMD 自动向量化
- 缓存争用问题
- 多看看别人的代码,别人的优化,多用优秀的开源代码

浙公网安备 33010602011771号