c- AVX中的矩阵向​​量乘法不是比SSE中的比例快

我使用以下方法在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一起使用可能会导致问题,但是我用-mavx’标志使用g编译它应该删除SSE操作码.

我也可以使用:_mm256_storeu_ps(& C [i],sum)做同样的事情,但加速是一样的.

关于我可以做些什么来提高性能的任何见解?它可以与:performance_memory_bound相关,虽然我不明白该线程的答案.

此外,即使包含“immintrin.h”头文件,我也无法使用_mm_fmadd_ps()指令.我启用了FMA和AVX.

解决方法

我建议你重新考虑你的算法.参见讨论 Efficient 4×4 matrix vector multiplication with SSE: horizontal add and dot product – what’s the point?

你正在做一个长点产品并且每次迭代使用_mm_hadd_ps.相反,你应该使用SSE一起做四个点产品(8个用AVX)并且只使用垂直操作符.

您需要添加,乘法和广播.这可以通过_mm_add_ps,_mm_mul_ps和_mm_shuffle_ps(用于广播)在SSE中完成.

如果你已经有了矩阵的转置,这非常简单.

但无论你是否有转置,你都需要让代码更加缓存友好.为了解决这个问题,我建议对矩阵进行循环平铺.请参阅此讨论What is the fastest way to transpose a matrix in C++?,以了解如何进行循环平铺.

在尝试SSE / AVX之前,我会尝试先将循环平铺放到第一位.我在矩阵乘法中获得的最大提升不是来自SIMD,也不是来自循环平铺的线程.我认为如果你获得了缓存使用权,你的AVX代码也会比SSE更加线性.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...