【问题标题】:Is using a stride of 1 still critical to vDSP performance today?对于今天的 vDSP 性能,使用 1 的步幅是否仍然至关重要?
【发布时间】:2013-03-23 02:51:09
【问题描述】:

helpful but somewhat dated 2006 年 11 月关于使用 vDSP 对代码进行矢量化的文章中,作者声明:

要记住的重要一点是,只有使用 步幅等于 1 将提供极快的矢量化代码。

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

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

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

我现在最常调用的 vDSP 例程是 vDSP_distancesq,以防万一。

【问题讨论】:

    标签: performance vectorization intrinsics vdsp vmat


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我的期望很高,但我不想在没有先询问的情况下放弃使用更广泛兼容的内存布局的想法。感谢您的及时回复!我想现在我必须想出一个 C 计划……
    • 这就是为什么gemmgemv 只接受(小)步幅= 1 的数组吗?我一直想知道为什么它没有实现(小)步幅 > 1。我理解性能损失,但是对于小步幅,比如 2 或 3,它应该是可能的并且仍然会有所收获。
    【解决方案2】:

    是的。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多