性能优化

性能优化

1. 这些是一些常见操作的成本的数量级的概念:

这些操作的精确耗时取决于许多因素,包括硬件/操作系统/网络条件等.以下是一些大致的估计:

  1. 一次内存访问:大约在100纳秒级别.这是从CPU访问主内存的时间,缓存访问会更快.

  2. 一次函数调用:大约在几十到几百纳秒.这取决于函数的复杂性和编译器优化.

  3. 一次字符串比较:取决于字符串的长度和比较算法,可能在几微秒到几十微秒.这假设字符串已经在CPU缓存中.

  4. 一次系统调用:大约在1-10微秒.这是进入内核并返回用户空间的时间,不包括系统调用本身的执行时间.

  5. 一次磁盘访问:
    • 对于固态硬盘(SSD),大约在0.1毫秒(100微秒).
    • 对于机械硬盘(HDD),大约在5-10毫秒.
  6. 一个通过网络的消息的成本:取决于网络的延迟和带宽,可能在几毫秒到几百毫秒.例如,一个典型的局域网延迟可能在0.1-1毫秒,而跨大洲的延迟可能在100-200毫秒.

2. 代码优化主要思路

  • 编译器优化
  • 高效使用C++
    • 优化算法实现,避免不必要的递归;避免在循环中创建和销毁对象
    • 避免不必要的计算和wait;避免不必要的参数copy
    • 利用计算资源,现在cpu很多时候都可以对指令并行化,利用simd特性
    • 编写硬件友好型的代码
  • 面向硬件优化

3. 编译器优化

3.1 pgo

PGO,全称为 Profile-Guided Optimization(基于分析的优化),是一种编译器优化技术,它通过收集程序运行时的性能信息来指导编译器优化.

PGO 的工作流程通常包括以下几个步骤:

  1. 编译:首先,你需要使用特殊的编译器选项来编译你的程序,这会使得程序在运行时收集性能信息.

  2. 运行:然后,你需要运行你的程序,并让它处理一些典型的工作负载.这会生成一个性能分析文件,其中包含了程序运行时的性能信息.

  3. 优化编译:最后,你需要再次使用特殊的编译器选项来编译你的程序,这次编译器会使用性能分析文件中的信息来指导优化.

通过这种方式,编译器可以了解到程序的实际运行情况,例如哪些代码经常被执行,哪些代码很少被执行,哪些条件分支的预测结果通常是什么等等.然后,编译器可以使用这些信息来进行更有效的优化,例如更精确地进行内联,更智能地安排代码布局,更准确地预测条件分支等等.

PGO 可以显著提高程序的运行速度,特别是对于那些性能敏感的应用程序.然而,PGO 也有一些缺点,例如它会增加编译时间和编译复杂性,因此并不是所有的项目都适合使用 PGO.

3.2 设置target architecture

对于一般的客户端软件,设置目标架构并进行特定优化通常不是必需的,因为大多数情况下,编译器默认生成的代码已经足够高效,并且可以在各种不同的处理器上运行.

然而,如果你正在开发一些性能关键的软件,如游戏/图形渲染器/科学计算软件等,那么针对特定架构进行优化可能会带来显著的性能提升.在这种情况下,你可以考虑为你的目标平台设置目标架构,并使用相应的优化选项.

需要注意的是,如果你为一个特定的处理器优化了代码,那么这段代码在其他类型的处理器上可能无法运行,或者运行效率较低.因此,你需要考虑你的软件将在哪些平台上运行,并可能需要提供多个版本的二进制文件,以支持不同的处理器.

此外,设置目标架构并进行优化可能会使编译过程变得更复杂,并可能使得代码更难以调试和维护.因此,在决定是否进行这种优化时,你需要权衡其可能带来的好处和代价.