0

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

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 游戏创建最佳优化代码。

更新:我说的是 xnamath.h(d3d sdk) 中的 XMVECTOR - 16 个字节,4 个浮点数。

4

5 回答 5

7

这不是那种有助于概括的事情。

谷歌搜索XMVECTOR,我得到

typedef __m128 XMVECTOR;

因此,尽管是 16 个字节,但它都是一个 SSE 机器寄存器,所以你当然应该按值传递这个傻瓜。引用寄存器中的某些内容只会冒着将其强制入栈的风险。

编辑:即使您没有使用上面的 typedef,XMVECTOR也可能是编译器以不同方式处理的特殊类型。请注意有关 Xbox 平台的说明。无论如何,我在下面所说的话是双重的:


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

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

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

于 2013-07-29T23:04:26.957 回答
1

Vector编辑:有关16 字节长的详细信息,请参见底部。

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

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

在第二种情况下,向量被复制[除非编译器可以内联代码并且编译器可以意识到发生了什么,并删除额外的副本]。如果向量有 10000 个元素,那就是向量中任何内容的 10000 个副本。

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

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

确保基准具有代表性——你可以通过将 10k 个元素的速度提高 100 倍,然后在元素数量少于 20 时速度降低 2 倍——平均为 11...

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

同样,在“正常”类型负载下进行基准测试。

于 2013-07-29T22:56:41.513 回答
0

过早的优化是万恶之源。

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

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

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

正如@Potatoswatter 注意到的那样,如果您通过引用传递它,您的 CPU 将优化这种类型。

于 2013-07-29T22:54:41.530 回答
0

通过引用传递的向量参数会更快,对于其中包含许多元素的向量来说更是如此。这样,您就可以避免花费在制作本地副本上的时间。

于 2013-07-29T22:45:03.113 回答
0

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

  1. 复印
  2. 对象切片

这两种情况你都不想发生。

于 2013-07-29T22:46:32.303 回答