使用 SSE 进行打包 16 元素混合的最佳方法

问题描述 投票:0回答:1

我想使用SSE实现以下功能。它将 a 中的元素与 b 中的打包元素混合在一起,其中元素仅在使用时才出现。

void packedBlend16(uint8_t mask, uint16_t* dst, uint16_t const* a, uint16_t const* b) {
  for (int i = 0; b < 8; ++i) {
    int const control = mask & (1 << i);
    dst[i] = control ? a[i] : *b++;
  }
}

对我来说最棘手的部分是在向量中正确间隔 b 的元素。

到目前为止,我的做法是:

  1. 256 条目
    LUT[mask]
    进行随机播放,使用
    pshufb
  2. 在正确的位置扩展 b 的元素
  3. 使用
    vpbroadcastw
    +
    vpand
    +
    vpcmpeqw
  4. 从蒙版构造混合向量
  5. pblendvb
    a
    b
  6. 的已打乱元素

我怀疑 256 个条目的 LUT 不是最好的方法。我可能有 2 个 16 条目 LUT 用于高位/低位。但是您必须根据掩码的较低 4 位的 popcnt 向较高的 LUT 添加偏移量。

我一次独立执行其中 4 个操作,因此我希望最大化吞吐量,但可以接受延迟。

我还可以采取其他方法吗?

assembly x86 x86-64 intel sse
1个回答
0
投票

使用 pdep 指令将 b 的元素打包到连续的内存块中,使用 vpshufb 指令将 b 的元素打乱到正确的位置,vpblendw 指令将 a 和 b 的元素混合在一起。

© www.soinside.com 2019 - 2024. All rights reserved.