SSE中的0xFFFF标志

时间:2015-06-22 08:34:17

标签: c vectorization sse

我想创建一个SSE寄存器,其值可以存储在一个整数数组中,来自另一个包含标志0xFFFF和零的SSE寄存器。例如:

__m128i regComp = _mm_cmpgt_epi16(regA, regB);

为了论证,我们假设regComp加载了{ 0, 0xFFFF, 0, 0xFFFF }。我想把它转换成说{ 0, 80, 0, 80 }

我想到的是创建一个整数数组,初始化为80并将它们加载到寄存器regC。然后,执行_mm_and_si128 bewteen regCregComp并将结果存储在regD中。但是,这并不能解决问题,这让我觉得我不理解SSE寄存器中的正标志。有人可以回答这个问题并简要解释为什么我的解决方案不起作用吗?

short valA[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
short valB[16] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10 };
short ones[16] = { 1 };
short final[16];

__m128i vA, vB, vOnes, vRes, vRes2;

vOnes = _mm_load_si128((__m128i *)&(ones)[0] );

for( i=0 ; i < 16 ;i+=8){
   vA = _mm_load_si128((__m128i *)&(valA)[i] );
   vB = _mm_load_si128((__m128i *)&(valB)[i] );

   vRes = _mm_cmpgt_epi16(vA,vB);

   vRes2 = _mm_and_si128(vRes,vOnes);
   _mm_storeu_si128((__m128i *)&(final)[i], vRes2);
 }

2 个答案:

答案 0 :(得分:2)

您只将数组ones的第一个元素设置为1(数组的其余部分初始化为0)。

我建议你完全摆脱数组ones,然后改变这一行:

vOnes = _mm_load_si128((__m128i *)&(ones)[0] );

为:

vOnes = _mm_set1_epi16(1);

可能是一个更好的解决方案,如果您只是想将SIMD TRUE(0xffff)结果转换为1,那么将使用一个班次:

for (i = 0; i < 16; i += 8) {
    vA = _mm_loadu_si128((__m128i *)&pA[i]);
    vB = _mm_loadu_si128((__m128i *)&pB[i]);

    vRes = _mm_cmpgt_epi16(vA, vB);    // generate 0xffff/0x0000 results

    vRes = _mm_srli_epi16(vRes, 15);   // convert to 1/0 results

    _mm_storeu_si128((__m128i *)&final[i], vRes2);
}

答案 1 :(得分:1)

尝试加载1:

vOnes = _mm_set1_epi16(1);

这比创建常量数组要短。

注意,在C ++中提供的数组值小于数组大小,将其他值初始化为零。这是你的错误,而不是SSE部分。

不要忘记调试器,现代调试器正确显示SSE变量。