【问题标题】:C/C++ Performance Globals vs Get/Set MethodsC/C++ 性能全局变量与获取/设置方法
【发布时间】:2010-10-03 20:44:58
【问题描述】:

我看到这个问题询问是否globals are bad。

当我考虑它的后果时,我能想到的唯一论点是它们在某些情况下是必要的,这可能是出于性能原因。

但是,我不太确定。所以我的问题是,使用全局会比使用 get/set 方法调用更快吗?

【问题讨论】:

    标签: c++ c performance methods global


    【解决方案1】:

    一个好的现代编译器应该内联 get/set 方法调用,这样可能没有真正的区别。

    在几乎任何情况下,担心静态/全局变量是否会导致您头疼比担心性能影响更重要,因为性能影响无论如何都几乎无法检测到。

    【讨论】:

    • 编译器内联 getter 和 setter 可能适用于 C/C++,但读者不应将其推广到其他语言,因为您在 Java 中并不总是看到这一点。
    • 我猜在 Java 中这并不重要。
    • litb:您是在嘲笑 Java 的性能,还是指的是 Java 不允许全局变量这一不明显的事实? ;-)
    • 您仍然可以拥有公共类成员变量并避免使用 setter 和 getter。
    • @Blaisorblade 够公平的!感谢您的澄清。由于语言类型(本机与 VM)的根本差异,我相信你是对的,双方都有不同的优势,包括 VM 绑定语言可能在进行更多动态优化方面具有巨大优势。一种 PGO 存在于 C++ 编译器中——例如 GCC 的反馈导向优化,I learned and then rambled about here——但出于同样的原因,它必须更多地是一个手动的迭代过程:compile/profile/compile/zzz跨度>
    【解决方案2】:

    它可能会稍微快一点,但速度不会有很大的提高。不过,全局变量对所有事物都具有 getter 和 setter 函数确实可以减小应用程序的大小。这种类型的大小节省是否对您的应用程序有益与您的目标平台相关。例如,在开发嵌入式应用程序、内存有限的平台时,它可能是一个可行的解决方案。

    【讨论】:

      【解决方案3】:

      您可以通过用汇编程序编写来获得更多性能。而且还会浪费更多时间来调试代码。

      这是完全相同的交易类型。

      【讨论】:

      • 好点,但在这里无关紧要。高级语言的优化器可以消除这种愚蠢权衡的需要。他们可能永远不会让你避免编写一个智能算法而不是一个糟糕的算法,但现在小函数的函数调用开销已成为历史(如果你在标题中声明函数)。
      • 这基本上是我的观点。编写好的代码,这就是编译器编写者在编写优化器时所关心的。
      【解决方案4】:

      更合适的比较是访问全局(静态)和本地。

      确实,全局更快,因为访问局部需要将变量偏移量添加到堆栈指针的值。

      然而,你永远,永远需要担心这个。尝试专注于重要的事情,例如使您的代码可读、可写和工作。

      【讨论】:

      • 在嵌入式和操作系统代码中确实非常重要,如果代码不执行,它就不起作用。访问全局通常比访问本地慢,因为您需要通过 GOT。当然,这取决于 ABI 和架构。
      • Locals 通常会更快,因为它们可以在寄存器中分配(有时)并且通常具有更好的参考位置。
      • 即使本地不在寄存器中,在堆栈帧中访问内存与绝对地址是否存在惩罚是完全依赖于体系结构的(特别是因为堆栈帧指针通常总是已经在寄存器中)。
      • 很高兴认识大家!我一直认为实际的 ESP+offset 添加是不可避免的。我还必须阅读有关 GOT 的信息
      • ESP + 偏移量的添加是不可避免的,一个像样的处理器将为此专门配备晶体管。以至于优化器经常通过地址单元(使用 LEA 指令)使用这些晶体管对“a*2+c”表达式进行编码。我认为 GOT 不用于二进制中的变量,仅用于共享库中的变量。本地通常比全局快,因为(在合理的堆栈大小下,没有大缓冲区)它更有可能在缓存中(避免缓存未命中约 100 个周期),编码其地址所需的空间更少,并且可以已注册。
      【解决方案5】:

      这取决于 CPU 和编译器。在至少一个流行的 PPC 芯片组上,加载全局变量需要额外的指令,因为它不能以 16 位相对偏移量编码。

      另外,它可能会在缓存局部性和/或破坏任何假设没有别名的优化。假设全局变量可以提高性能有点幼稚。

      【讨论】:

      • 在 MIPS 等其他 CPU 上,有一个专门用于全局变量的寄存器,因此全局访问与堆栈访问一样快(假设所有全局变量都适合 64K。编译器通常会将小的全局变量自动出现。
      • 而在 ARM 上,您通常需要从文字池中读取地址,这不仅速度慢,而且会污染您的缓存。
      • @Mark James,我认为这也带来了另一个问题:污染全局变量空间也会使这种优化变得更加困难。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 2015-06-12
      • 2023-03-12
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多