是否知道两种变体中的哪一种更快,或者它们是相同的,或者比较不正确。
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个浮点数。
答案 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)
除非需要传递地址,否则应始终通过引用传递对象,例如,如果您还想允许空指针。按值传递对象意味着:
你想要发生这两件事。
答案 4 :(得分:0)
这主要是过早的优化。这也是一种微观优化。因此,它需要更多关于Vector
类型和所需用法,编译器以及许多其他因素的知识。
这两者并不相等;后者不接受rvalues并允许该函数改变向量。您应该使用const&
使它们非常相似。
你说这是一个D3D应用程序;在这种情况下(预计算除外),您真的想在GPU上进行矢量和矩阵计算。简单的分析器无济于事,您需要分析CPU和GPU代码。
正如@Potatoswatter注意到的,这是一种类型,你的CPU将优化得更多,如果你通过引用传递它。