【问题标题】:Ramp function for Intel SSE英特尔 SSE 的斜坡功能
【发布时间】:2015-04-07 18:09:21
【问题描述】:

我正在将我的 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);

}

}

【问题讨论】:

  • 依赖与乘法?
  • 原码是什么?您的新代码的 MCVE (stackoverflow.com/help/mcve) 是什么?您在哪些平台上运行它们?你是如何衡量执行时间的?
  • 参考代码添加到原帖。使用 Instruments 时间分析器在 XCode 下使用 LLVM 编译。我从一个 _mm_add_ps 和 _mm_store_ps 开始。这太糟糕了,我决定稍微展开循环,确实有点帮助:)

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


【解决方案1】:

您在a1a2a2a3a3acc 以及acca1 之间存在数据依赖关系。这为您的循环每 4*(ADDPS 的延迟)周期执行一次循环迭代的速度设置了一个绝对下限 = 1 次循环迭代/12-16 个周期(具体数字取决于您的目标架构) .

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

相反,计算最初的四个向量,并在每次通过循环时将增量添加到每个向量的四倍。这样,它们就不会相互依赖,您的循环运行速度可以提高 3-4 倍。你可能仍然比vDSP_vramp 慢一些,因为你没有对对齐做任何特别的事情,你也没有在支持它的机器上利用 AVX,但这至少会让你进入正确的球场。

【讨论】:

    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2016-07-04
    • 2012-11-14
    • 2017-09-28
    相关资源
    最近更新 更多