1

Core2のコードをベクトル化したい。gccまたはiccの組み込み関数を使用でき、SSE、SSE2、SSE3、SSSE3命令が許可されていると思います。

私のコードは8つのuint32_t要素の配列で機能し、次のようになります(ホットスポットのみがここにあります)。

const uint32_t p[8] = {2147483743, 2147483713, 2147483693, 2147483659, 
 2147483647, 2147483629, 2147483587, 2147483579};
void vector_mod_add(uint32_t *a /* a[8] */, uint32_t *b /* b[8] */) {
    int n;
    for(n=0;n<8;n++)
        a[n]+=b[n];
    for(n=0;n<8;n++)
        if(a[n]>=p[n])
            a[n]-=p[n];
}

足し算はかなり簡単ですが、条件付き引き算がどうやってできるのかわかりません。

また、SSE2を使用した手動ベクトル化の経験がないので、ここですべての型を定義する方法を教えてください。

4

1 に答える 1

3

あなたはそれをとして書くことができますa[n] -= p[n] & ~(a[n] < p[n])。ここ<はCのものではなく、SSEのもの(pcmpltd)であり、真の要素ごとに-1を返し、偽の要素ごとに0を返し(AND演算を可能にするため)、&~ですpandn。コードの試みは次のとおりです。

__m128i a, p;
a = _mm_sub_epi32(a, _mm_andnot_si128(_mm_cmplt_epi32(a, p), p));

これは署名された操作を使用するため、2^31 - 1正しく機能するには、数値を下に保つ必要があることに注意してください。それを超える必要がある場合は、に変更_mm_cmplt_epi32(a, p)します_mm_cmplt_epi32(_mm_xor_si128(a, signs), _mm_xor_si128(p, signs))。ここで、signsは要素がすべて。である32ビットワードのベクトルです0x80000000。これは、より広い範囲をより効率的に処理するように見えるバージョンです。

__m128i a, p;
a = _mm_sub_epi32(a, p);
a = _mm_add_epi32(a, _mm_and_si128(_mm_srai_epi32(a, 31), p));
于 2011-03-13T02:42:46.110 に答える