【问题标题】:Vectorizing Code for efficient implementation向量化代码以高效实施
【发布时间】:2013-04-05 09:08:24
【问题描述】:

以下是IIR code。我需要对代码进行矢量化处理,以便高效地编写 NEON 代码。

矢量化示例 非矢量化代码

for(i=0;i<100;i++)
a[i] =a[i]*b[i];     //only one independent multiplication cannot take
                     //advantage of multiple multiplication units

矢量化代码

for(i=0;i<25;i++)
{
a[i*4] =a[i*4]*b[i*4];                //four  independent multiplications can use
a[(i+1)*4] =a[(i+1)*4]*b[(i+1)*4];    // multiple multiplication units to perform the 
a[(i+2)*4] =a[(i+2)*4]*b[(i+2)*4];    //operation in parallel
a[(i+3)*4] =a[(i+3)*4]*b[(i+3)*4];
}

请帮助我将下面的for循环向量化,以便利用硬件的向量能力有效地实现代码(我的硬件可以同时执行4次乘法)。

 main()
    {
        for(j=0;j<NUMBQUAD;j++)
    {
        for(i=2;i<SAMPLES+2 ;i++)
        {
            w[i] = x[i-2] + a1[j]* w[i-1] + a2[j]*w[i-2];
            y[i-2] = w[i] + b1[j]* w[i-1] + b2[j]*w[i-2];

        }
        w[0]=0;
        w[1] =0;
    }
    }

【问题讨论】:

  • 首先让它工作。我可能弄错了,但通常 IIR 访问前馈循环中的多个元素。这仅访问 x[i-2]。
  • @Aki 所说的 - 尝试优化损坏的代码是没有意义的。对于 IIR 过滤器,您有问题的依赖关系 - 实际上,与 4 路 SIMD 并行实现 4 个单独的 IIR 过滤器比尝试将 SIMD 应用于单个 IIR 过滤器更容易。
  • 这是双二阶 IIR 的另一种形式,方程采用 en.wikipedia.org/wiki/Digital_biquad_filter#Direct_Form_2
  • @PaulR 这是大多数人在我看到的各种代码中所做的。有没有办法至少部分改进代码?

标签: optimization parallel-processing arm vectorization neon


【解决方案1】:

确定(或验证)方程式后,您应该注意到方程式的每一轮都有 4 个独立的乘法。任务变成找到将输入向量 x[...]、y[...]、w[...] 置换到某个寄存器的正确且最少数量的指令

   q0 = | w[i-1] | w[i-2] | w[i-1] | w[i-2]|
   q1 = | a1[j]  | a2[j]  | b1[j]  | b2[j] |   // vld1.32 {d0,d1}, [r1]!
   q2 =   q0 .* q1

一种可能更有效的波前并行方法可以通过反转for循环来实现。

   x0 = *x++;

   w0 =  x0 + a*w1 + b*w2;  // pipeline warming stage
   y0 =  w0 + c*w1 + d*w2;  // 

   [REPEAT THIS]
     // W2 = W1; W1 = W0;
     W0 = y0 + A*W1 + B*W2;
     Y0 = W0 + C*W1 + D*W2;
     // w2 = w1; w1 = w0;

     x0 = *x++;
     *output++= Y0;

     w0 = x0 + a*w1 + b*w2;
     y0 = w0 + c*w1 + d*w2;
   [REPEAT ENDS]

   W0 = y0 + A*W1 + B*W2;   // pipeline cooling stage
   Y0 = W0 + C*W1 + D*W2;
   *output++= Y0;

虽然 x0->w0->y0->W0->Y0 之间仍然存在依赖关系,但在小写和大写表达式之间存在完全 2 向并行性的机会。也可以尝试通过展开循环并进行手动寄存器重命名来摆脱值 w2=w1; w1=w0; 的移位。

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2011-07-23
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多