我想在宽度为128,256或512位的CPU寄存器(xmm,ymm或zmm)上执行单个位,位对和半字节(4位)的任意置换; 这应该尽可能快.为此,我正在研究SIMD指令.有没有人知道这样做的方法/实现它的库?我在Windows上使用MSVC,在Linux上使用GCC,主机语言是C或C++.谢谢!
我给了一个任意的排列,需要改组大量的位向量/对位向量/半字节.我知道如何为64位值内的位执行此操作,例如使用Benes网络.
或在更广泛的SIMD寄存器,例如使用昂纳雾的GPL协议VectorClass库(洗牌周围的8位和更大的块https://www.agner.org/optimize/vectorclass.pdf)为构建洗牌出来的模板元编程功能在给予shuffle作为模板参数的情况下,AVX2通道内字节混洗和/或大元素通道混洗.
然而,对于置换的更细粒度细分 - 分为1,2或4位块 - 似乎很难在宽向量上实现.
我能够对排列进行预处理,例如提取位掩码,根据需要计算索引,例如Benes网络,或者其他任何东西 - 很高兴在另一种高级语言中这样做,所以假设排列以最方便解决问题的格式给出; 包括小型查找表.
我希望代码比做类似的事情要快得多
// actually 1 bit per element, not byte. I want a 256-bit bit-shuffle
const uint8_t in[256] = get_some_vector(); // not a compile-time constant
const uint8_t perm[256] = ...; // compile-time constant
uint8_t out[256];
for (size_t i = 0; i < 256; i ++)
out[i] = in[perm[i]];
Run Code Online (Sandbox Code Playgroud)
正如我所说的,我有一个<= 64位(64位,32位对和16位半字节)的解决方案.在较宽的SIMD寄存器上,对于大小为8,16,32等的块也解决了该问题.
编辑:澄清一下,置换是一个编译时常量(但不仅仅是一个特定的,我会根据给定的排列编译程序).