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

前端之家收集整理的这篇文章主要介绍了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&C++相关文章