gcc shuffle()函数和SIMD代码生成

n3h0vuf2  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(164)

我一直在考虑ecatmur的constexprswap()函数,我认为它是一个更通用的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()的公式,clang和gcc喜欢对现有的指令集进行更多的SIMD化,可能使用内置函数或内部函数?我并不是针对特定的指令集。

guicsvcw

guicsvcw1#

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)) | ...);
}

我们可以看到,一个常量与一次移位操作的结果进行了AND运算,操作数彼此独立,这使得表达式更适合于矢量化。

相关问题