从AVX寄存器中提取并存储备用低32位

时间:2016-10-20 02:22:16

标签: vectorization simd intrinsics avx2

我有一个__m256i寄存器,我想从每个64位组中提取4个低32位,打包它们并将它们连续存储到内存中。即,如果__m256i寄存器包含8个32位字:{a0,a1,a2,a3,a4,a5,a6,a7},我想连续地将四个字{a0,a2,a4,a6}存储到存储器中

我想出了以下代码:

void mystore(uint32 *dst, const __m256i& src)
{
      __m256 ps256    = _mm256_castsi256_ps(src);
      __m128 lo128    = _mm256_extractf128_ps(ps256, 0);
      __m128 hi128    = _mm256_extractf128_ps(ps256, 1);
      __m128 pack128  = _mm_shuffle_ps(lo128, hi128, 0 + (2<<2) + (0<<4) + (2<<6));
      __m128i r    = _mm_castps_si128(pack);
     _mm256_storeu_si256( reinterpret_cast<__m128i*>(dst), r )
}

如果我是正确的,那么转换操作只是为了满足编译器类型检查,但它们实际上等效于无操作,因此shuffle指令和2提取指令的总延迟成本为3,加上未对齐商店的成本。

有更快的方法吗?

由于

1 个答案:

答案 0 :(得分:2)

您可以尝试使用以下内容:

const __m256i K_PERM = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7);

inline void mystore(uint32_t * dst, const __m256i & src)
{
    __m256i permuted = _mm256_permutevar8x32_epi32(src, K_PERM);
    __m128i lo128 = _mm256_extractf128_si256(permuted, 0);
    _mm_storeu_si128((__m128i*)dst, lo128);
}