我将我的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);
}
}
答案 0 :(得分:3)
您在a1
和a2
,a2
和a3
,a3
和acc
以及acc
之间存在数据相关性}和a1
。这设置了循环可以执行每4 *循环迭代的速度的绝对最低值(ADDPS
}循环的延迟= 1循环迭代/ 12-16循环(具体数字取决于您的体系结构)定位)。
相反,计算初始的四个向量,并在每次通过循环时为每个向量添加四倍的增量。这样,它们不会相互依赖,并且您的循环可以快3-4倍。你可能仍然比vDSP_vramp
慢一点,因为你没有做任何关于对齐的特殊事情,你没有在支持它的机器上利用AVX,但这至少会让你进入正确的球场