我想使用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 的元素。
到目前为止,我的做法是:
LUT[mask]
进行随机播放,使用 pshufb
vpbroadcastw
+ vpand
+ vpcmpeqw
pblendvb
a
与 b
我怀疑 256 个条目的 LUT 不是最好的方法。我可能有 2 个 16 条目 LUT 用于高位/低位。但是您必须根据掩码的较低 4 位的 popcnt 向较高的 LUT 添加偏移量。
我一次独立执行其中 4 个操作,因此我希望最大化吞吐量,但可以接受延迟。
我还可以采取其他方法吗?
使用 pdep 指令将 b 的元素打包到连续的内存块中,使用 vpshufb 指令将 b 的元素打乱到正确的位置,vpblendw 指令将 a 和 b 的元素混合在一起。