use*_*122 7 c++ sse vectorization avx matrix-multiplication
我正在使用以下内容在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);
}
Run Code Online (Sandbox Code Playgroud)
我对AVX使用了类似的方法,但最后,由于AVX没有等效的指令_mm_store_ss(),我用过:
_mm_store_ss(&C[i],_mm256_castps256_ps128(sum));
Run Code Online (Sandbox Code Playgroud)
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.
我建议你重新考虑你的算法.请参阅讨论使用SSE进行高效4x4矩阵向量乘法:水平加点和点积 - 有什么意义?
你正在做一个长点产品并使用_mm_hadd_ps每次迭代.相反,你应该使用SSE一起做四个点产品(八个用AVX)并且只使用垂直操作符.
您需要添加,乘法和广播.这都可以在上证所完成用_mm_add_ps,_mm_mul_ps和_mm_shuffle_ps(用于广播).
如果你已经有了矩阵的转置,这非常简单.
但无论您是否有转置,您都需要使代码更加缓存友好.为了解决这个问题,我建议对矩阵进行循环平铺.请参阅此讨论在C++中转置矩阵的最快方法是什么?了解如何进行循环平铺.
在尝试SSE/AVX之前,我会先尝试将循环平铺放到第一位.我在矩阵乘法中获得的最大提升不是来自SIMD,也不是来自循环平铺的线程.我认为如果你获得了缓存使用权,你的AVX代码也会比SSE更加线性.
| 归档时间: |
|
| 查看次数: |
5014 次 |
| 最近记录: |