英特尔SSE的斜坡功能

时间:2015-04-07 18:09:21

标签: c++ optimization signal-processing intel sse

我将我的OsX DSP库移植到Windows。从vDSP_ramp开始,大量使用。该函数产生增加值C [i] = C [i-1] + A

的斜坡

这是我使用内在函数的SSE版本(我向累加器和存储添加了一个增量向量)

 __m128 acc = {A[0],A[0]+(*B),A[0]+2*(*B), A[0]+3*(*B)};//_mm_set1_ps(0.0);
    float i1 = 4*(*B);
    __m128 inc = {i1,i1,i1,i1};

    int ln = N/4/4;

    for(int i=0; i<ln; i++) {
        __m128 a1 =  _mm_add_ps(acc, inc);
        __m128 a2 =  _mm_add_ps(a1, inc);
        __m128 a3 =  _mm_add_ps(a2, inc);
        acc       =  _mm_add_ps(a3, inc);

        _mm_store_ps(C, a1);
        _mm_store_ps(C+4, a2);
        _mm_store_ps(C+8, a3);
        _mm_store_ps(C+12, acc);
        C+=16;
    }

我甚至展开了循环,但它仍然需要比原始vdsp_ramp函数多5倍的时间。

我该如何进一步优化?这有什么不对?

Edit1:参考代码:

void BSDSP_vramp(
             const float *A,
             const float *B,
             float       *C,
             unsigned long  N) {

for(int i=0; i<N; i++) {
    C[i] = (*A)+i*(*B);

}

}

1 个答案:

答案 0 :(得分:3)

您在a1a2a2a3a3acc以及acc之间存在数据相关性}和a1。这设置了循环可以执行每4 *循环迭代的速度的绝对最低值(ADDPS}循环的延迟= 1循环迭代/ 12-16循环(具体数字取决于您的体系结构)定位)。

像这样的依赖性是矢量化的主要罪。只是不要这样做。

相反,计算初始的四个向量,并在每次通过循环时为每个向量添加四倍的增量。这样,它们不会相互依赖,并且您的循环可以快3-4倍。你可能仍然比vDSP_vramp慢一点,因为你没有做任何关于对齐的特殊事情,你没有在支持它的机器上利用AVX,但这至少会让你进入正确的球场