下面是一个IIR码。我需要将代码向量化,这样我才能高效地编写霓虹灯代码。
向量化非矢量化代码示例
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;
}
}发布于 2013-04-05 09:34:58
一旦你有固定(或验证)方程,你应该注意到,有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之间仍然存在依赖关系,但在小写表达式和大写表达式之间存在完全双向并行的机会。另外,还可以尝试通过展开循环并进行手动寄存器重命名来改变值w2=w1; w1=w0;。
https://stackoverflow.com/questions/15829930
复制相似问题