静态、常量和全局变量带来的性能提升

Performance gain from static, const and global variables

本文关键字:性能 常量 全局变量 静态      更新时间:2023-10-16

是否可以通过声明变量staticconst或使其成为global来获得C++中的性能?

将内置类型的函数局部变量放在其他地方不太可能胜过它:如果变量的值可以在编译时计算,那么将其作为constexpr将是理想的。

  • 在确定对象是否已经初始化的函数的每次调用中,生成变量static可能会产生较小的开销,尤其是在C++11中,初始化是线程安全的。即使不需要检查,堆栈也可能在缓存内存中,而static变量则不在
  • 使变量全局化会增加它不在缓存内存中的可能性,也就是说,它很有可能会变慢(除了其他不利的可能性,比如使它成为引入数据竞赛的好候选者)
  • 如果编译器可以将变量const计算为编译时,那么生成变量可能会有所帮助

如果变量具有非平凡类型,事情会变得更有趣,因为初始化成本,例如std::vector<T>的初始化成本是非平凡的。与全局对象相比,我不希望使对象static具有局部功能(即,我不会使它们具有全局功能;无论如何,全局对象都没有空间)。然而,使对象static引入了它们可以在线程之间共享的可能性。如果这是一个问题,那么添加的锁定和序列化可能会破坏任何潜在的节约,使用基于堆栈的内存的分配器是提高成本的更好方法(假设它们足够小,可以在堆栈上合理使用)。

性能取决于许多因素,不能认为简单地更改这些细节就能真正提高性能。

提高性能的最佳方法是了解实现的细节,并应用分析工具来识别真正的瓶颈。

大多数时候,人们倾向于提前优化代码,耗费大量精力,使代码在对应用程序的整体性能没有太大影响的部分无法读取。

干杯

查看编译器生成的汇编代码。

我观察到static const变量将直接访问只读内存位置中的数据,而不是在堆栈上分配和复制数据。

static全局变量和全局变量之间的性能增益可以忽略不计(几乎不可估量)。通过编码来帮助编译器将变量放入寄存器,可以获得更好的结果。

您还可以通过将数据设置为适合单个数据缓存行来获得性能。处理器可以将数据一次提取到其缓存中并在那里引用,而不是从外部存储器中提取。

当然,如果您想要更显著的性能提升,可以减少函数调用和分支(跳转)。这些导致处理器重新加载指令缓存,这比从外部存储器访问数据变量花费更多的时间。

如果使用全局变量,调试将浪费更多时间。一般来说,程序的开发成本大于其性能。有些游戏程序需要数年时间才能开发,但多年来从未执行过。