我一直在考虑 ecatmur 的 constexpr
swap()
函数,我相信这是更通用的 shuffle()
函数的特例:
template <std::size_t ...I, std::size_t ...J, typename T>
constexpr T shuffle(T const i, std::index_sequence<J...>) noexcept
{
return ((std::uint8_t(i >> 8 * I) << 8 * J) | ...);
}
I
是源索引,J
是目标索引。有许多不同的方法可以实现 shuffle()
(我不会向你详细介绍),但是,根据我的经验,这些实现不会导致 gcc 和 clang 同样好地生成 SIMD 代码,当在循环中调用 shuffle()
。因此我的问题。是否存在 shuffle()
的公式,clang 和 gcc 比现有的更喜欢 SIMDify,可能使用内置函数或内在函数?我的目标不是特定的指令集。
最佳答案
template <std::size_t ...I, std::size_t ...J, typename T>
constexpr T shuffle(T const i, std::index_sequence<J...>) noexcept
{
return ((T{0xff} << 8 * J) & (I < J ? i << 8 * (J - I) : i >> 8 * (I - J)) | ...);
}
我们看到一个常量与单个移位运算的结果相与,操作数彼此独立,使表达式更适合向量化。
关于c++ - shuffle() 函数和 SIMD 代码生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65022124/