我正在尝试将逻辑验证问题矢量化以在 Intel 64 上运行。
我将首先尝试描述问题:
我有一个v[]
70 位整数的静态数组(其中大约 400,000 个),它们在编译时都是已知的。
生产者创建 70 位整数a
,其中很多,非常快。
对于每个a
我需要找出是否存在一个元素 from v
which v[i] & a == 0
。
到目前为止,我在 C 中的实现是这样的(简化的):
for (; *v; v++) {
if (!(a & *v))
return FOUND;
}
// a had no matching element in v
return NOT_FOUND;
我正在考虑使用 SSE/AVX 来优化这一点,以加快流程并并行执行更多这些测试。我尽可能地加载a
并*v
进入一个XMM
寄存器并调用PTEST
指令进行验证。
我想知道是否有办法扩展它以使用新YMM
寄存器的所有 256 位?也许将 3x70 位打包到一个寄存器中?我不太清楚如何有效地打包/解包它们,以证明每个测试不仅仅使用一个寄存器。
关于输入的性质,我们知道几件事:
- 中的所有元素
v[]
都设置了很少的位 - 不可能以
v[]
任何方式置换/压缩以使其使用少于 70 位 - 平均检查大约 20% 后,该
FOUND
条件有望得到满足。v[]
a
在批量检查它们之前,可以缓冲一个以上。- 我不一定需要知道
v[]
匹配的哪个元素,只需要知道那个匹配或不匹配。 - 生产
a
只需要很少的内存,所以之前调用在 L1 中留下的任何东西都可能仍然存在。
生成的代码旨在在支持 SSE4.2、AVX 指令的最新一代英特尔至强处理器上运行。我很乐意接受使用英特尔 C 编译器或至少 GCC 编译的程序集或 C。