c - AVX2 64位无符号整数比较

标签 c integer compare avx2

我正在尝试比较两个 __m256i (4 个打包的 64 位整数)。为此,我使用 _mm256_cmpgt_epi64功能。

除了一些比较之外,该函数按预期工作,就好像该函数没有考虑 64 位整数的最大位一样。如下图第二次和第三次对比。

这里是一个 MCVE,我希望来自 a 的每个 64 位整数都大于来自 b 的同级整数(因此 cp 应该为0xFFF...FFF):

#include <immintrin.h>
#include <x86intrin.h>
#include <stdio.h>
#include <inttypes.h>

// gcc mcve.c -mavx2 -madx && ./a.out

int print_avx2_hex256(__m256i ymm)
{
    const size_t n = sizeof(__m256i) / sizeof(u_int64_t);
    u_int64_t buffer[n];
    _mm256_storeu_si256((__m256i*)buffer, ymm);
    for (int i=0; i<n; ++i)
        printf("%016"PRIx64" ", buffer[i]);
    printf("\n");

    return 0;
}

int compare(__m256i a, __m256i b)
{
    __m256i cp = _mm256_cmpgt_epi64(a,b);

    print_avx2_hex256(cp); // Comparison
    print_avx2_hex256(a);
    print_avx2_hex256(b);

    return 0;
}

int main()
{
    u_int64_t _a[4] = {0xf, 0xf000000000000000, 0xd00000000000000d, 0x0f00000000000000};
    u_int64_t _b[4] = {0x2, 0x2000000000000000, 0x2000000000000002, 0x0200000000000000};

    __m256i a   = _mm256_setr_epi64x(_a[0], _a[1], _a[2], _a[3]);
    __m256i b   = _mm256_setr_epi64x(_b[0], _b[1], _b[2], _b[3]);

    compare(a,b);
    return 0;
}

但是我的输出如下(按 cpab 的顺序):

ffffffffffffffff 0000000000000000 0000000000000000 ffffffffffffffff 
000000000000000f f000000000000000 d00000000000000d 0f00000000000000 
0000000000000002 2000000000000000 2000000000000002 0200000000000000 

我不熟悉英特尔内部函数,所以如果有人能告诉我我做错了什么,我将不胜感激:)

最佳答案

您的问题是 _mm256_cmpgt_epi64 比较有符号整数,因此如果您在其中一个 i64 上设置最高有效位,则会被视为负数。例如,0xf000000000000000 是负数,0x2000000000000000 不是,而_mm256_cmpgt_epi64(正确地)告诉您后者更大。

看起来没有严格等效的函数来比较无符号整数,但您可以使用 _mm256_cmpgt_epu64_mask,它返回一个 __mmask8 位字段。

编辑:忘记提及 _mm256_cmpgt_epu64_mask 需要 AVX512,您可能无法使用它。

关于c - AVX2 64位无符号整数比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52150530/

相关文章:

JavaFX TextField 转 Int

c++ - 如何将用户输入与字符串进行比较?

PHP:如何将一个数组中的键与另一个数组中的值进行比较,并返回匹配项?

c - (C) 允许输入无限个数字,反转输入数字的顺序,输入 0 时结束程序

c - 函数指针返回值的问题

c - 如何指定正确的 'return type' ?

c - 使用 fscanf 从文件中读取字符串后读取整数

c++ - 理解 void* 对 intptr_t 和 uintptr_t

python - 在线文件比较工具

c - 如何在模块化编程中使用结构?