转换AVX2 / ymm寄存器内3位值的有效方法

时间:2019-12-01 08:42:28

标签: c sse simd avx avx2

我有一个有趣的问题,无法想到用矢量化代码解决的有效方法。

我有一个ymm寄存器,其中包含8个32位整数,其中每个整数均由以下组成:

  • 低24位是8 x 3bit“个”值
  • 8位包含一个单个 3位值,与该问题“无关”,但理想情况下,我会保留 该值保持不变,而不会触碰到3位。 我可以在前8位之内自由移动3位的值,但我想保留 理想的地方...

我想做的是找到一种方法来“转置” 3位值,以便(显示前3个元素):

Legend: 
z -> 8 Top-level bits I'd like to keep in place/don't care about)
a..x -> groups of 3-bit values I'd like to transpose over the ymm register
vvvv Source vvvv
-----------------
|MSB                          LSB|MSB                          LSB|MSB                          LSB|...
|zzzzzzzz...............cccbbbaaa|zzzzzzzz...............kkkjjjiii|zzzzzzzz...............sssrrrqqq|...
|zzzzzzzz...............qqqiiiaaa|zzzzzzzz...............rrrjjjbbb|zzzzzzzz...............ssskkkccc|...
-----------------
^^^^ Dest ^^^^

我可以执行8x(extract + pdep + vmovq + vpmovzxbd + vpslld + vpor)次运算的:

// N, is a constant 0..7
__m256i src;
__m256i dest;
 _mm256_or_si256(
    dest, 
    _mm256_slli_epi32(
      _mm256_cvtepi8_epi32(
        _mm_cvtsi64_si128(
         _pdep_u64(_mm256_extract_epi32(src, N), 0x707070707070707)
        )
      ), 
      3
    )
  );

但这大约是6x8条指令来执行转置。 我想认为可以使用AVX2进行一些魔术操作,可以使这种操作变得更短/更快,但是如果有人对我的操作有任何指导,我现在无法提出任何建议可以做不同的事情,我会非常感激。

0 个答案:

没有答案