5

MMX、SSE、SSE2、および SSE3 のみをサポートする Intel Atom プロセッサに移植する必要があるパフォーマンス クリティカルなアプリケーションを開発しています。私の以前のアプリケーションは AVX だけでなく SSSE3 もサポートしていましたが、今は Intel Atom プロセッサ (MMX、SSE、SSE2、SSE3) にダウングレードしたいと考えています。

特にssse3命令_mm_hadd_epi16をこのコードに置き換えると、パフォーマンスが大幅に低下します

RegTemp1 = _mm_setr_epi16(RegtempRes1.m128i_i16[0], RegtempRes1.m128i_i16[2], 
                          RegtempRes1.m128i_i16[4], RegtempRes1.m128i_i16[6],
                          Regfilter.m128i_i16[0],   Regfilter.m128i_i16[2],
                          Regfilter.m128i_i16[4],   Regfilter.m128i_i16[6]);

RegTemp2 = _mm_setr_epi16(RegtempRes1.m128i_i16[1], RegtempRes1.m128i_i16[3],
                          RegtempRes1.m128i_i16[5], RegtempRes1.m128i_i16[7],
                          Regfilter.m128i_i16[1],   Regfilter.m128i_i16[3],
                          Regfilter.m128i_i16[5], Regfilter.m128i_i16[7]);

RegtempRes1 = _mm_add_epi16(RegTemp1, RegTemp2);

これは、この特定の命令に対して私が思いついた最高の変換です。しかし、この変更はプログラム全体のパフォーマンスに深刻な影響を与えました。

MMX、SSE、SSE2、および SSE3 命令内で、よりパフォーマンス効率の高い代替案を命令に提案して_mm_hadd_epi16ください。前もって感謝します。

4

2 に答える 2

3

目標が 8 つの 16 ビット値の水平方向の合計を取ることである場合は、次のように SSE2 でこれを行うことができます。

__m128i sum1  = _mm_shuffle_epi32(a,0x0E);             // 4 high elements
__m128i sum2  = _mm_add_epi16(a,sum1);                 // 4 sums
__m128i sum3  = _mm_shuffle_epi32(sum2,0x01);          // 2 high elements
__m128i sum4  = _mm_add_epi16(sum2,sum3);              // 2 sums
__m128i sum5  = _mm_shufflelo_epi16(sum4,0x01);        // 1 high element
__m128i sum6  = _mm_add_epi16(sum4,sum5);              // 1 sum
int16_t sum7  = _mm_cvtsi128_si32(sum6);               // 16 bit sum
于 2014-02-21T11:03:09.763 に答える