如何检查 256i(16 位)向量以了解它是不是包含任何大于零的元素?

Posted

技术标签:

【中文标题】如何检查 256i(16 位)向量以了解它是不是包含任何大于零的元素?【英文标题】:How to examine a 256i (16-bit) vector to know if it contains any element greater than zero?如何检查 256i(16 位)向量以了解它是否包含任何大于零的元素? 【发布时间】:2015-02-23 23:17:30 【问题描述】:

我正在将矢量化代码从 SSE2 内在函数转换为 AVX2 内在函数, 并且想知道如何检查 256i(16 位)向量是否包含任何大于零的元素。以下是 SSE2 中使用的代码:

int check2(__m128i vector1, __m128i vector2)

  __m128i vcmp =  _mm_cmplt_epi16(vector2, vector1);
  int cmp = _mm_movemask_epi8(vcmp);
  return ((cmp>0) ? 1 : 0) ;

我认为下面的代码可以工作,但它没有。

int check2(__m256i vector1, __m256i vector2)

  __m256i vcmp = _mm256_cmpgt_epi16(vector1, vector2);
  int cmp = _mm256_movemask_epi8(vcmp);
  return ((cmp>0) ? 1 : 0) ;

如果有人可以提供建议,我将不胜感激

【问题讨论】:

你能解释一下它是如何“不起作用”的吗? 它没有像 SSE2 代码那样返回正确的答案,我怀疑问题与 _mm256_movemask_epi8 函数有关。也许它应该被另一个函数替换,不是吗? 请注意gt 不是lt 的补码。为什么要更改参数的顺序? 没有基于 LT (_mm256_cmplt_epi16) 的内置指令。但是,使用 GT 交换参数应该返回相同的结果。 我在这里感觉到XY problem。如果您要与零进行比较,为什么该函数需要两个向量? 【参考方案1】:

我认为你只是有一个微不足道的错误 - 你的功能应该是:

int check2(__m256i vector1, __m256i vector2)

    __m256i vcmp = _mm256_cmpgt_epi16(vector1, vector2);
    int cmp = _mm256_movemask_epi8(vcmp);
    return cmp != 0;

问题在于_mm256_movemask_epi8 将 32 位标志作为有符号整数返回,并且您正在测试 > 0。显然如果 MS 位为 1,那么此测试将失败(因为结果将是

【讨论】:

感谢大家,特别感谢 Paul .. 它就像一个魅力 ^_^

以上是关于如何检查 256i(16 位)向量以了解它是不是包含任何大于零的元素?的主要内容,如果未能解决你的问题,请参考以下文章

在 __m128i 向量上水平检查零?

从 bool (i1) 向量到 i8、i16 等的 LLVM 位转换是不是定义明确?

如何格式化数字 0..9 以显示 2 位数字(它不是日期)

Armv8a NEON 内联汇编代码:如何将 16x8 位向量转换为四个 4x32 位(整数)向量?

随机播放 16 位向量 SSE

在 Matlab 中读取和写入二进制文件