C++ _mm256_移动掩码_epi8至uint64_t

C++ _mm256_移动掩码_epi8至uint64_t,c++,visual-c++,type-conversion,intrinsics,sign-extension,C++,Visual C++,Type Conversion,Intrinsics,Sign Extension,有人能解释一下为什么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打印

有人能解释一下为什么tr2tr4显示不同的结果:

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打印0xFFFFFFFFFFFF,tr4打印0x00000000FFFFFFFF

做为tr4有什么表现吗

<>我对C++和本质都是新的,所以我可能忽略了一些明显的东西。

我使用VisualStudio 2019 C++编译器。

正如上面提到的保罗,这与具有较大整数的带符号/无符号的赋值有关。下面是一个例子:

#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";
}

所以Paul是对的,但值得注意的是,如果将有符号数分配给更高的位宽度字段,则不会发生这种情况。

正如Paul上面所说的,这与使用更大的整数分配有符号/无符号有关。下面是一个例子:

#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";
}

因此Paul是对的,但值得注意的是,如果您将有符号的数字分配给更高的位宽度字段,则不会发生这种情况。

\u mm256\u movemask\u epi8
返回一个
int
(当然是
有符号的
),因此这只是通常的C(或C++)类型升级规则。与SIMD或intrinsic本身无关。
\u mm256\u movemask\u epi8
返回一个
int
(当然是
有符号的),因此这只是通常的C(或C++)类型升级规则。与SIMD或intrinsics本身无关。