Filter 可以为ARM NEON并行化过滤器吗?
我试图弄清楚一个特定的现有代码是否可以并行化,以及如何在ARM Cortex-A9 NEON SIMD单元中使用。代码如下:Filter 可以为ARM NEON并行化过滤器吗?,filter,arm,simd,neon,Filter,Arm,Simd,Neon,我试图弄清楚一个特定的现有代码是否可以并行化,以及如何在ARM Cortex-A9 NEON SIMD单元中使用。代码如下: for(int i=0; i < 11; i++) { f4UF1 *= F[i]; A[i][2] = A[i][1]; A[i][1] = A[i][0]; A[i][0] = f4UF1; B[i][2] = B[i][1]; B[i][1] = B[i][0]; C[i] = 0; C[
for(int i=0; i < 11; i++)
{
f4UF1 *= F[i];
A[i][2] = A[i][1];
A[i][1] = A[i][0];
A[i][0] = f4UF1;
B[i][2] = B[i][1];
B[i][1] = B[i][0];
C[i] = 0;
C[i] += D[i][0] * A[i][0];
C[i] += D[i][1] * A[i][1];
C[i] += D[i][2] * A[i][2];
C[i] -= E[i][1] * B[i][1];
C[i] -= E[i][2] * B[i][2];
B[i][0] = C[i] / E[i][0];
f4UF1 = B[i][0];
}
for(int i=0;i<11;i++)
{
f4UF1*=F[i];
A[i][2]=A[i][1];
A[i][1]=A[i][0];
A[i][0]=f4UF1;
B[i][2]=B[i][1];
B[i][1]=B[i][0];
C[i]=0;
C[i]+=D[i][0]*A[i][0];
C[i]+=D[i][1]*A[i][1];
C[i]+=D[i][2]*A[i][2];
C[i]=E[i][1]*B[i][1];
C[i]=E[i][2]*B[i][2];
B[i][0]=C[i]/E[i][0];
f4UF1=B[i][0];
}
我已经看了相当多的代码了,我几乎可以肯定它不能被有效地并行化,但是我想,我可以试着在这里问一下。我并不期待现成的代码,只是关于如何做到这一点的想法。谢谢:)是的,这看起来确实像是一个双四元组,每个样本的系数都会改变,可能是因为您正在平滑它们 正如一位评论者所提到的,您可能希望预先计算
1/E[i][0]
比例因子,并可能将其滚动到其他系数中以减少乘法的数量,特别是在浮点平台上。您还可以经常规范化双四元组,以消除D[i][0]
(使其成为1.0
),只需对整个输出应用标量
当然,您可能已经意识到,您希望在循环期间将所有内容都保存在寄存器中,然后在循环完成后才将它们写入内存…;-)
之后,我知道了两种矢量化技术(尽管我也对Nils的想法感兴趣):
数据类型是什么?您应该粘贴能够满足编译器要求的内容。编译它并检查输出可能会提供一些见解。您可以使用vext指令向下滑动元素。您也可以进行乘法/加法运算。如果你用NEON写的话,看起来你可以把事情改进几个周期。唯一的问题是需要转换成乘法的除法。这是一个标准的双四元滤波器,对吗?好吧,如果你能接受一些全局输出延迟,那么有一些技巧可以并行化它。@Nilsippenbrinck:+1用于识别它的双四元组;不过,如果能为您提到的优化机会提供一些指导,那就太好了。