我正在使用以下内容编写SSE和AVX的矩阵向量乘法:
for(size_t i=0;i<M;i++) {
size_t index = i*N;
__m128 a, x, r1;
__m128 sum = _mm_setzero_ps();
for(size_t j=0;j<N;j+=4,index+=4) {
a = _mm_load_ps(&A[index]);
x = _mm_load_ps(&X[j]);
r1 = _mm_mul_ps(a,x);
sum = _mm_add_ps(r1,sum);
}
sum = _mm_hadd_ps(sum,sum);
sum = _mm_hadd_ps(sum,sum);
_mm_store_ss(&C[i],sum);
}
我在AVX中使用了类似的方法,但是由于AVX没有与_mm_store_ss()
等效的指令,在最后我使用了:
_mm_store_ss(&C[i],_mm256_castps256_ps128(sum));
SSE代码使我的程序在串行代码的基础上加速了3.7倍。然而,AVX代码只使我的程序在串行代码的基础上加速了4.3倍。
我知道使用SSE和AVX可能会引起问题,但我使用g++编译时使用了“-mavx”标志,应该可以去除SSE操作码。
我也可以使用:_mm256_storeu_ps(&C[i],sum)
来做同样的事情,但加速效果是相同的。
有什么其他的见解可以改善性能吗?这可能与performance_memory_bound有关,尽管我没有清楚地理解那个线程上的答案。
此外,即使包括“immintrin.h”头文件,我也无法使用_mm_fmadd_ps()指令。我已经启用了FMA和AVX。
_mm_store_ss(&C[i],_mm256_castps256_ps128(sum));
是AVX中的等效指令。SSE指令只操作256位AVX寄存器的低128位。强制转换只是为了让编译器满意,不使用任何指令。 - Z boson