如何向量化这个内核?

时间:2014-03-24 18:02:01

标签: c performance sse

我在另一个问题的中间提出了这个问题,似乎没有人会在上一个主题中回答这个问题。

我的问题如下。我成功地将一个应用程序向量化。但是,对于这个特定的内核:

inline int cFunction(Node** A, Node* B){

    long dot = 0, i;

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

    if(abs(2 * dot) <= B->norm)
            return 0;

    long q = round((double) dot / B->norm);

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

    (*A)->norm = (*A)->norm + q * q * B->norm - 2 * q * dot;

    return 1;

}

我只能对第一个循环进行矢量化。如果我把icpc运行这个代码,用:

 icpc *.c *.h -g -O2 -msse4.2 -vec-report=1

我有以下报告:

main.c(558):(第9栏)评​​论:LOOP是VECTOREDED。

main.c(566):(第2栏)评论:LOOP是VECTORIZED。

这告诉我icpc实际上是对代码进行矢量化。现在,如果我手动矢量化第一个循环,我对整数有一个很好的(完美?)加速因子。这告诉我编译器在向量化时没有做得很好(特别是因为如果我使用 s,性能是相同的)。但是,对于第二个循环,如果我像这样手动矢量化,我得不到任何性能提升:

    const int q = round((double) dot / B->norm) ;

    int32_t * pA = (*A)->data;
    int32_t * const pB = B->data;

    const __m128i vecQi = _mm_set1_epi32(q);

    __m128i vecResi, vecPi, vecCi, vecQCi;

    for(i=0;i<SIZE-3;i+=4){
            vecPi = _mm_load_si128((__m128i *)&(pA)[i] );
            vecCi = _mm_load_si128((__m128i *)&(pB)[i] );
            vecQCi = _mm_mullo_epi32(vecQi,vecCi);
            vecResi = _mm_sub_epi32(vecPi,vecQCi);
            _mm_store_si128((__m128i *) ((pA) + i), vecResi );
    }

    for(;i<SIZE;i++)
            pA[i] -= q * pB[i];

    (*A)->norm = (*A)->norm + q * q * B->norm - 2 * q * dot;

有没有人知道为什么我没有通过矢量化第二个内核来获得性能提升?

感谢。

0 个答案:

没有答案