2

在2006 年 11 月关于使用vDSP对代码进行矢量化的一篇有用但有些过时的文章中,作者发表了以下声明:

需要记住的重要一点是,只有步幅等于 1 的操作才能交付极快的矢量化代码。

今天仍然如此吗?即使在具有更强大矢量内在函数的更新的英特尔处理器上?

我之所以问是因为我正在编写一些矩阵数学例程,并且刚刚开始将它们全部切换为使用类似于 Fortran的列优先排序,以便更容易地与MATLABBLASLAPACK兼容。但现在我发现我对vDSP的一些调用需要处理不再连续的向量……</p>

目前,这些vDSP调用是我的代码执行的瓶颈例程。并不是说这将永远如此,但至少现在我不想放慢它们的速度,只是为了让对其他库的调用更简单。

我现在最常调用的vDSPvDSP_distancesq例程是为了以防万一。

4

2 回答 2

4

尚真。AFAIK(从 SSE4.x 开始,我认为 AVX 不会改变这一点)SSE 内存加载指令仅加载连续块。

您可以以 2 的步幅进行矢量化,但需要一些额外的混洗操作。

为了一次从缓存中加载整个 SSE 寄存器,这实际上是一个适合同一缓存行的问题。(而且内存 -> 缓存传输的数量对性能更为关键)。

为了支持 scatter-gather SSE,需要大更新的不是 SIMD 指令,而是缓存和内存控制器。

于 2013-04-01T23:30:51.903 回答
3

是的。

如果有充分的理由,我们(Apple 的 Vector and Numerics Group)可以为某些其他步幅添加优化。例如,对于 2 步长,在某些处理器模型上,我们会照常加载向量块,但然后使用各种置换指令仅提取每个其他元素。这将导致代码不如单元步长代码快,但会比当前代码快。这并不经常这样做,因为通常还有其他更好的方法,例如将跨步数据复制到单位跨度缓冲区,在缓冲区上执行多个 vDSP 操作,然后将数据复制回来。

您描述的案例似乎不是专门研究非单位步幅的好人选。如果您正在对数组的连续列执行多个 vDSP_distancesq 操作,最好并行执行(一次多列)而不是串行执行(所有列,然后是另一列,...)。如果您只对隔离列执行单个 vDSP_distancesq 操作,则还有其他问题。矩阵上的列操作因缓存问题而臭名昭著,尤其是当每行的字节数是 2 的相当大的幂的倍数时。该操作可能会受到内存负载的限制,因此编写专门的代码来优化计算可能没有任何好处。

于 2013-04-03T13:50:08.957 回答