【问题标题】:Performance gain from static, const and global variables [closed]静态、常量和全局变量的性能提升 [关闭]
【发布时间】:2014-01-09 22:53:24
【问题描述】:

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

【问题讨论】:

  • 相比什么?什么类型的变量?变量的使用频率如何?答案是:视情况而定。
  • 也许吧。但出于性能原因不要这样做
  • 与在函数中定义它们相比。
  • 一般来说,这会导致完全不同的语义。您无法比较行为不同的程序的性能。当它影响语义时,它是无法回答的:性能取决于几乎无限多的因素,而你只给出了一个。我猜想明显差异为零,但无论如何你都不应该担心它。有比性能更重要的事情,当性能成为您的首要任务时,有十亿种比这种猜测更好的方法来改进它。
  • @delnan 也很认真。这个问题的答案不可能一概而论。

标签: c++


【解决方案1】:

您不太可能将内置类型的函数局部变量放在其他地方,除非:如果可以在编译时计算变量的值,则将其设置为 constexpr 将是理想的。

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

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

【讨论】:

  • 某个东西是否在缓存中与它在 C++ 级别的声明方式无关,只与它的地址以前被使用的频率(多久、多久……)有关。堆栈实际上总是在缓存中,因为它几乎总是被使用,是的,但是一个广泛使用的全局变量也将在缓存中。
  • @delnan:好的,所以我们有:堆栈很有可能在缓存中,全局变量很有可能在缓存中如果它经常使用,否则概率较低。如果我们将这两个方面放在一起,我认为我们可以得出全局变量在缓存中的机会可能小于堆栈中的变量,因此访问全局变量的机会更高慢点。我用了其他词,但我就是这么说的。您在哪里不同意访问权限?
  • 也许我们在这里应用了不同的量词?您似乎对所有可能的全局变量进行了平均。我假设该程序一开始就对缓存友好,因为否则缓存将变得一团糟,而且效果有限。我对您的措辞也有疑问,对我来说,无论缓存中是否存在某些内容,都像是纯粹的运气(取决于存储说明符)。它是可测量的并且通常很容易预测(尽管这需要全局查看代码及其内存使用情况),并且完全可以使用例如全局变量,以便它们位于缓存中。
【解决方案2】:

性能取决于许多因素,您不能假设简单地更改这些细节会真正提高性能。

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

大多数时候,人们倾向于及早优化代码,在对应用程序整体性能没有太大影响的部分投入大量精力并使代码不可读。

干杯

【讨论】:

    【解决方案3】:

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

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

    static 全局变量和全局变量之间的性能提升可以忽略不计(几乎无法衡量)。通过编码以帮助编译器将变量放入寄存器中,您将获得更好的结果。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 2015-10-04
      相关资源
      最近更新 更多