在 SSE 中进行比较时的奇怪行为

Posted

技术标签:

【中文标题】在 SSE 中进行比较时的奇怪行为【英文标题】:Strange behaviour when comparing in SSE 【发布时间】:2018-03-19 11:40:34 【问题描述】:

我的代码中没有出现错误。我尝试将 unsigned char 值的缓冲区与常量进行比较。然后我想根据比较存储 1 或 0 。这是我的代码(在结构中):

void operator()(const uint8* src, int32 swidth, int32 sheight, uint8* dst, uint8 value) 
   uint8 t[16];
   __m128i v_one = _mm_set1_epi8((uint8)1);
   __m128i v_value = _mm_set1_epi8(value);

   printf("value = %d\n", value);
   SHOW(t, v_one);
   SHOW(t, v_value);
   std::cout << "****" << std::endl;

   for (int32 i = 0; i < sheight; ++i) 
      const uint8* sdata = src + i * swidth;
      uint8* ddata = dst + i * swidth;
      int32 j = 0;
      for ( ; j <= swidth - 16; j += 16) 
         __m128i s = _mm_load_si128((const __m128i*)(sdata + j));
         __m128i mask = _mm_cmpgt_epi8(s, v_value);

         SHOW(t, s);
         SHOW(t, mask);
         std::cout << std::endl;
      
   

我的第一行是我所期望的:

value = 100
  1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100

但是我的比较是错误的:

214 100 199 203 232  50  85 195  70 141 121 160  93 130 242 233
  0   0   0   0   0   0   0   0   0   0 255   0   0   0   0   0

我真的不明白错误在哪里。

SHOW 宏是:

#define SHOW(t, r)                  \
  _mm_storeu_si128((__m128i*)t, r); \
  printf("%3d", (int32)t[0]);       \
  for (int32 k = 1; k < 16; ++k)    \
    printf(" %3d", (int32)t[k]);    \
  printf("\n")

【问题讨论】:

给我;最明显的错误是您没有使用 std::vector(或 std::array),因为这意味着您不能;看功能;知道传递给它的内存是否有效。 见How to create a Minimal, Complete, and Verifiable example 【参考方案1】:

您正在将s 数组中的元素与value 数组中的元素进行比较。

value 数组中的所有值都是 100。 您的 s 数组中有多种值。

但是,_mm_cmpgt_epi8 适用于 有符号 值,因为这些是字节,它会考虑从 -128 到 +127 的值。

因此,大于 100 的唯一可能值是 101 到 127 范围内的值。

因为您在该范围内只有 1 个值 (121),所以这是唯一一个设置了掩码的值。

要查看此内容,请将uint8 t[16]; 更改为int8 t[16];,您应该会得到更符合预期的结果。

【讨论】:

没错。我发现这个问题解释了如何为感兴趣的人比较 unsigned char。谢谢 ! ***.com/questions/33824300/…

以上是关于在 SSE 中进行比较时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

这种悲伤教学的奇怪行为的原因是啥?

对 JMS 队列上的消息进行计数时的奇怪行为

使用 Twitch 进行身份验证时的 Spring-Boot OAuth2 奇怪行为

在使用 Android 2.2 的 HTC Desire 上使用 Android MediaPlayer 进行流式传输时的奇怪行为

核心数据:使用延迟实例化时的奇怪错误行为

使用 websocket 时的奇怪行为