Performance 间接daxpy操作的高效实现

Performance 间接daxpy操作的高效实现,performance,linear-algebra,sse,simd,blas,Performance,Linear Algebra,Sse,Simd,Blas,_axpy是blas一级操作,它实现以下功能 for i = 1:n a[i] = a[i]-$\alpha$ b[i] 通过各种blas库(如MKL)可以有效地实现这种常规的daxpy 在我的例子中,我想实现以下使用间接寻址的daxpy操作变体 for i = 1:n a[ind1[i]] = a[ind1[i]]-$\alpha$ b[i] 其中ind1包含需要更新的向量A的元素索引。我得到的信息是,ind1是一个单调数组,即$ind1[I]>ind[j]\_forall

_axpy是blas一级操作,它实现以下功能

for i = 1:n
    a[i] = a[i]-$\alpha$ b[i]
通过各种blas库(如MKL)可以有效地实现这种常规的daxpy

在我的例子中,我想实现以下使用间接寻址的daxpy操作变体

for i = 1:n
    a[ind1[i]] = a[ind1[i]]-$\alpha$ b[i]
其中ind1包含需要更新的向量A的元素索引。我得到的信息是,ind1是一个单调数组,即$ind1[I]>ind[j]\_foralli>j$


我假设这种计算经常出现在稀疏线性代数中。是否有人知道基于SSE/AVX的此类例程的任何有效实现

你可以做
movss
,然后做3个
insrps
,直到你填充一个向量,然后再做数学运算。然后分散回各个位置?如果索引是16位或32位,您可以将多个索引一次加载到64位GP寄存器中,然后shift+
movzx
以获取数组索引

例如,见。该函数根据16位字的高半部和低半部查找16位GF16 longmultiply分量。所以我的索引是8位的,所以我可以在一个64位的加载中得到很多


如果索引中有足够多的连续数据,值得大量分支预测失误查找,那么正如@StephenCanon所说,只需查找运行并使用SIMD执行每个连续块就值得了。

如果
ind1
数组包含连续运行,您可以采取一些措施来加快操作。如果
ind1
本质上是任意的,那么您几乎无法对此进行优化(可能除了预取)。SSE/AVX根本没有进行必要的聚集/分散操作的有效方法。它确实包含连续运行,但可能长度为10-30。我的猜测是预取可能会起作用,但有人警告我,手动预取可能弊大于利