在函数定义中使用引用参数:性能?

时间:2013-07-29 22:35:55

标签: c++ performance optimization

是否知道两种变体中的哪一种更快,或者它们是相同的,或者比较不正确。

Vector test(Vector &vec)
{
 // return modified vector, or write directly to vec,
 // or do not return anything, but access vec anyway
}

Vector test(Vector vec)
{
 // same (but no reference)
}

我在问,因为我应该知道,为Direct3D游戏创建最佳优化代码。

UPDATE :我在谈论xnamath.h中的XMVECTOR(d3d sdk) - 16个字节,4个浮点数。

5 个答案:

答案 0 :(得分:7)

这不是一般有用的东西。

Google搜索XMVECTOR,我

typedef __m128 XMVECTOR;

因此,尽管是16个字节,但它只是一个SSE机器寄存器,所以你当然应该按值传递这个吸盘。在寄存器中引用某些东西只会将它强制进入堆栈。

编辑:即使您没有使用上述typedef,XMVECTOR仍可能是编译器区别对待的特殊类型。观察有关XBox平台的说明。在任何情况下,我在下面说的都是双重的:


将微观优化视为惯用语是错误的方法。微优化从机器代码开始。这里的出发点应该是剖析器指向的任何机器指令,因为在任何程序中都有很多微小的部分,你不会凭直觉找到缓慢的部分。

如果您刚刚开始第一个优化项目,您应该研究不同的分析工具(告诉您程序的哪个部分很慢)并熟悉一个。一旦深入挖掘,当您无法通过调整源代码所要执行的 来提高速度时,您将不得不开始分析机器指令。这需要熟悉CPU及其指令集的详细信息。只有这样,你才能有用地开始调整源代码如何做小事的微不足道的差异。

如果您不太了解CPU如何执行指令,请不要跳到优化那种事情。考虑到大鱼在算法和程序的整体结构中,这完全是浪费时间。

答案 1 :(得分:1)

编辑:有关Vector的详细信息,请参阅下方16字节长。

如果向量具有多个元素(或者元素本身非常大),则第一个很可能明显更快。

然而,正如他们所说,“魔鬼在细节中”。在某些特定情况下,第二种情况确实可能更快。这将是一个例外,而不是规则,但它仍然是一种可能性。

在第二种情况下,正在复制向量[除非编译器可以内联代码并且编译器可以实现正在进行的操作,并删除额外的副本]。如果向量具有10000个元素,则为向量中的任何内容的10000个副本。

在第一种情况下,从调用函数传递给调用函数的所有内容都是单个指针。另一方面,由于它是一个引用,因此生成的代码必须再生成一个内存引用来读取内容。因此,如果向量非常小,并且test函数正在对vec变量进行相当多的访问,则间接的额外开销可能比“副本”的副本“更差”。内容。

如果有疑问,请对两种解决方案进行基准测试。

确保基准测试具有代表性 - 通过使10k元素的速度提高100倍,然后当元素数量小于20时最终速度降低2倍,平均值为11,就可以得到同样的错误。 。

编辑:由于问题已更新,我必须补充说“因为Vector对象非常小”,所以选择之间的差异要小得多。在32位系统上,通过引用传递选项可能仍然有一个小的好处[但是,正如我在上面所说,它与更Vector内容的更复杂访问相平衡。在64位系统上,传递两个寄存器值很可能比参考值快。

同样,“普通”类型加载下的基准。

答案 2 :(得分:0)

通过引用传递的向量参数会更快,如果向量中包含许多元素,则更快。这样你就可以避免花在制作本地副本上的时间。

答案 3 :(得分:0)

除非需要传递地址,否则应始终通过引用传递对象,例如,如果您还想允许空指针。按值传递对象意味着:

  1. 复制
  2. 对象切片
  3. 你想要发生这两件事。

答案 4 :(得分:0)

过早的优化是万恶之源。

这主要是过早的优化。这也是一种微观优化。因此,它需要更多关于Vector类型和所需用法,编译器以及许多其他因素的知识。

这两者并不相等;后者不接受rvalues并允许该函数改变向量。您应该使用const&使它们非常相似。

你说这是一个D3D应用程序;在这种情况下(预计算除外),您真的想在GPU上进行矢量和矩阵计算。简单的分析器无济于事,您需要分析CPU和GPU代码。

正如@Potatoswatter注意到的,这是一种类型,你的CPU将优化得更多,如果你通过引用传递它。