c++ - 性能与 SSE 相同

标签 c++ performance vectorization sse

我矢量化了以下循环,它出现在我正在开发的应用程序中:

void vecScl(Node** A, Node* B, long val){

    int fact = round( dot / const);

    for(i=0; i<SIZE ;i++)
        (*A)->vector[i] -= fact * B->vector[i];

}

这是 SSE 代码:

void vecSclSSE(Node** A, Node* B, long val){

    int fact = round( dot / const);

    __m128i vecPi, vecQi, vecCi, vecQCi, vecResi;

    int sseBound = SIZE/4;

    for(i=0,j=0;  j<sseBound  ; i+=4,j++){

        vecPi = _mm_loadu_si128((__m128i *)&((*A)->vector)[i] );
        vecQi = _mm_set_epi32(fact,fact,fact,fact);
        vecCi = _mm_loadu_si128((__m128i *)&((B)->vector)[i] );
        vecQCi = _mm_mullo_epi32(vecQi,vecCi);
        vecResi = _mm_sub_epi32(vecPi,vecQCi);               
        _mm_storeu_si128((__m128i *) (((*A)->vector) + i), vecResi );

    }

    //Compute remaining positions if SIZE % 4 != 0 
    for(; i<SIZE ;i++)
        (*A)->vector[i] -= q * B->vector[i];

}

虽然这在正确性方面有效,但使用和不使用 SSE 时的性能完全相同。我正在编译代码:

 g++ *.cpp *.h -msse4.1 -march=corei7-avx -mtune=corei7-avx -mno-avx -mno-aes -Warray-bounds -O2

这是因为我没有分配(并相应地使用 SSE 函数)对齐内存吗?更改代码非常复杂,所以我暂时避免了这种情况。

顺便说一句,就进一步改进而言,考虑到我受制于 Sandy Bridge 架构,我能做的最好的是什么?

编辑:编译器尚未对代码进行矢量化。首先,我将 vector 的数据类型更改为 short,这不会改变性能。然后,我用 -fno-tree-vectorize 编译,性能是一样的。

非常感谢

最佳答案

如果您的数据很大,那么您可能只是受内存限制,因为每次加载/存储您执行的 ALU 操作非常少。

但是您可以尝试一些小的改进:

inline void vecSclSSE(Node** A, Node* B, long val){
                                            // make function inline, for cases where `val` is small

    const int fact = (dot + const / 2 - 1) / const;
                                            // use integer arithmetic here if possible

    const __m128i vecQi = _mm_set1_epi32(fact);
                                            // hoist constant initialisation out of loop

    int32_t * const pA = (*A)->vector;      // hoist invariant de-references out of loop
    int32_t * const pB = B->vector;

    __m128i vecPi, vecCi, vecQCi, vecResi;

    for(int i = 0; i < SIZE - 3; i += 4) {   // use one loop variable
        vecPi = _mm_loadu_si128((__m128i *)&(pA[i]));
        vecCi = _mm_loadu_si128((__m128i *)&(pB[i]));
        vecQCi = _mm_mullo_epi32(vecQi,vecCi);
        vecResi = _mm_sub_epi32(vecPi,vecQCi);
        _mm_storeu_si128((__m128i *)&(pA[i]), vecResi);
    }

    //Compute remaining positions if SIZE % 4 != 0
    for(; i<SIZE ;i++)
        pA[i] -= q * pB[i];

}

关于c++ - 性能与 SSE 相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22510614/

相关文章:

c++ - 如何在 Visual Studio 2017 C++ 编译时检查环境变量的存在?

python - 是否可以对 NumPy 数组的递归计算进行矢量化,其中每个元素都依赖于前一个元素?

arrays - 通过对 R 中不同索引求和来矢量化(或加速)双循环

c++ - 结构和数组(C++)如何使用一个数组将卷号分配给名称

c++ - 从 Codechef March Long 竞赛中获得 ANUGCD 中的 WA

c++ - Nlohmann json 获取类型推导

c++ - openmp嵌套循环处理性能

performance - 为什么 Spark 应用程序在 MaxGCPauseMillis 较低的情况下运行速度会慢很多?

Java 文件传输、EJB、SOAP 或 REST,性能比较

python - NumPy - 向量化涉及范围迭代器的循环