【问题标题】:Do more levels of indirection have a performance impact in C更多级别的间接是否会对 C 中的性能产生影响
【发布时间】:2014-10-16 16:29:53
【问题描述】:

如果我有一个包含结构数组的结构......然后

config.data.item[3].userFunction();

访问更好吗
itemType * item = &config.data.item;

item[3].userFunction();
item[4].userFunction();

还是和

一样
config.data.item[3].userFunction();
config.data.item[4].userFunction();

或者效率损失的级别数量是否有限制,编译器优化是否有任何影响?

非常感谢您提供的任何见解。

【问题讨论】:

  • 就个人而言,我认为第二种方式更好。这取决于编译器,但如果您关心效率,则不应在编译器的假设下编写代码。
  • 为了我的理智,我几乎总是在适用时使用一个命名良好的中间变量。由编译器来担心它选择执行的任何这样的小优化。 (即使它没有执行任何此类优化,并且程序运行得足够快 - 谁在乎?不是我。)
  • 与任何这些类型的问题一样,最好的方法是计时。我怀疑编译器(和优化设置)之间可能会有所不同,而且我还怀疑任何差异都会非常非常小。代码的可读性可能胜过任何差异。
  • 唯一确定的方法是写下两者并比较它们的性能。我的直觉告诉我,任何差异都是微不足道的,但你永远不会知道。话虽如此,首先是正确性的代码,然后是可读性/可维护性。不要在几个周期内牺牲意图的清晰性除非您未能满足硬性能要求。
  • @JohnBode 一般来说,你是对的。但在这种情况下,一些底层知识就足以知道两个变体应该表现出完全相同的性能。 “应该”,因为编译器有时非常疯狂的事情。

标签: c performance indirection multiple-indirection


【解决方案1】:

间接级别确实会在 CPU 周期和可读性方面产生影响。但是,在您的情况下,只有一级间接(函数指针)。点运算符在编译时产生到config 位置的偏移量。

不管怎样,创建一个变量来保存公共子表达式的结果是一个好主意,尤其是当你给这个变量一个有意义的名字时。然而,就 CPU 而言,您应该不会看到任何影响:如今,优化编译器在检测和优化常见子表达式方面非常出色,因此无论您使用哪种方式编写此特定代码片段,您都应该看到相同的性能。

【讨论】:

  • 这里没有间接级别。 OP应该有,但没有。可以直接访问item
  • @KarolyHorvath 好吧,userFunction 是一个指针,所以两个表达式的间接级别是一样的。
  • 谢谢,这就是我的意思。从比较这两种方法的角度来看,没有区别。
【解决方案2】:

即使你做了像 a->b 这样的直接间接级别,这可能会导致缓存和性能下降,即使是看起来很无辜的 abc[x].d 也需要仔细检查,因为 [x] 很可能将你推出缓存。

所以答案实际上是取决于缓存中的内容、缓存的大小以及结构的大小。

唯一真实的方法是在将要使用的情况下测试代码。你甚至不能单独测试它,因为这会给你缓存利用率的错误结果。

我想简而言之,在您测试并证明存在问题之前,甚至不要担心优化,然后看看重组结构字段或避免 derefs 是否有帮助...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多