_mm256_movemask_epi8 to uint64_t - PullRequest
       54

_mm256_movemask_epi8 to uint64_t

0 голосов
/ 12 марта 2020

Может кто-нибудь объяснить, почему tr2 и tr4 показывают другой результат:

auto test1 = _mm256_set1_epi8(-1);

    uint64_t tr2 = _mm256_movemask_epi8(test1);
    uint32_t tr3 = _mm256_movemask_epi8(test1);
    uint64_t tr4 = tr3;

_mm256_movemask_epi8 (test1) должен возвращать int32, поэтому его присваивают int64 следует просто назначить младшие биты.

Вместо этого tr2 печатает 0xFFFFFFFFFFFFFFFF и tr4 печатает 0x00000000FFFFFFFF

Есть ли какая-либо производительность при выполнении этого как tr4?

Я новичок в C ++ и встроенных функциях, поэтому, возможно, мне не хватает чего-то очевидного.

Я использую компилятор Visual Studio 2019 C ++.

1 Ответ

2 голосов
/ 12 марта 2020

Как сказал выше Павел, это связано с назначением подписанных / неподписанных больших целых чисел. Вот пример:

#include <iostream>
#include <iomanip>

int main()
{
    int32_t negInt = -1;
    uint32_t unInt = static_cast<uint32_t>(negInt);
    int64_t negBigInt = static_cast<int64_t>(negInt);
    uint64_t unBigInt = static_cast<uint64_t>(negInt);
    uint64_t fromUnsigned = static_cast<uint64_t>(unInt);

    std::cout << std::hex;
    std::cout << "0x" << std::setfill('0') << std::setw(16) << negInt << "\n";
    std::cout << "0x" << std::setfill('0') << std::setw(16) << unInt << "\n";
    std::cout << "0x" << std::setfill('0') << std::setw(16) << negBigInt << "\n";
    std::cout << "0x" << std::setfill('0') << std::setw(16) << unBigInt << "\n";
    std::cout << "0x" << std::setfill('0') << std::setw(16) << fromUnsigned << "\n";
}

Это печатает:

0x00000000ffffffff
0x00000000ffffffff
0xffffffffffffffff
0xffffffffffffffff
0x00000000ffffffff

Так что Павел прав, но, в частности, этого не произойдет, если вы назначите число со знаком поля большей битовой ширины.

...