我在我的应用程序中广泛使用3D数学。通过将矢量/矩阵库转换为SSE,AltiVec或类似的SIMD代码,可以实现多少加速?

有帮助吗?

解决方案

根据我的经验,我通常看到从x87到SSE的算法改进了3倍,并且更好比使用VMX / Altivec提高了5倍(因为复杂的问题与管道深度,调度等)。但是我通常只在我有数百或数千个数字操作的情况下这样做,而不是那些我一次只做一个矢量的那些。

其他提示

这不是整个故事,但可以使用SIMD进一步优化,看看Miguel关于何时用MONO实现SIMD指令的演示文稿,他在 PDC 2008


(来源: tirania.org

图片来自Miguel的博客文章。

对于一些非常粗略的数字:我听说有些人在 ompf.org 声称为某些人提速10倍 - 优化的光线追踪程序。我也有一些很好的加速。根据问题的不同,我估计我的例行程序介于2x和6x之间,其中许多都有一些不必要的存储和负载。如果您的代码中有大量分支,请忘记它,但对于自然数据并行的问题,您可以做得很好。

但是,我应该补充一点,你的算法应该设计用于数据并行执行。 这意味着如果你有一个你提到的通用数学库那么它应该采用打包向量而不是单个向量,否则你只会浪费你的时间。

E.g。像

这样的东西
namespace SIMD {
class PackedVec4d
{
  __m128 x;
  __m128 y;
  __m128 z;
  __m128 w;

  //...
};
}

大多数问题性能重要可以并行化,因为您最有可能使用大型数据集。你的问题听起来像是我过早优化的情况。

对于3D操作,请注意W组件中未初始化的数据。我已经看到SSE操作(_mm_add_ps)由于W中的数据错误而需要10倍正常时间的情况。

答案很大程度上取决于库正在做什么以及如何使用它。

增益可以从几个百分点增加到“几倍快”,最容易看到增益的区域是那些你不处理孤立的矢量或值的区域,但是多个矢量或值必须以同样的方式处理。

另一个领域是当您达到缓存或内存限制时,再次需要处理大量值/向量。

增益可能最激烈的领域可能是图像和信号处理,计算模拟以及网格上的一般3D数学运算(而不是孤立的向量)。

目前,x86的所有优秀编译器都默认生成SP和DP浮点数学的SSE指令。使用这些指令几乎总是比原生指令快,即使是标量操作,只要你正确安排它们。对于许多人来说,这将是一个惊喜,他们过去发现SSE“慢”,并且认为编译器无法生成快速的SSE标量指令。但现在,您必须使用开关来关闭SSE生成并使用x87。请注意,x87此时已被有效弃用,可能会完全从未来的处理器中删除。这样做的一个缺点是我们可能失去了在寄存器中进行80位DP浮点运算的能力。但是,如果您依靠80位而不是64位DP浮点数来获得精度,那么您的共识似乎是一致的,您应该寻找更精确的容错算法。

以上所有内容都让我感到非常惊讶。这非常直观。但数据谈判。

如果有的话,您很可能只会看到非常小的加速,并且过程将比预期的更复杂。有关详细信息,请参阅Fabian Giesen的无所不在的SSE矢量类文章。

  

无所不在的SSE矢量类:揭穿共同的神话

     

不那么重要

     

首先,你的矢量类对你的程序性能可能并不像你想象的那么重要(如果是的话,它更可能是因为你做错了,而不是因为计算效率低下)。不要误解我的意思,它可能是整个程序中最常用的类之一,至少在做3D图形时是这样。但是,仅仅因为向量操作是常见的并不会自动意味着它们会占据程序的执行时间。

     

不那么热

     

不容易

     

现在不是

     

永远不会

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top