【发布时间】:2012-10-04 18:27:10
【问题描述】:
我正在尝试对逻辑验证问题进行矢量化以在 Intel 64 上运行。
我将首先尝试描述问题:
我有一个静态数组 v[],包含 70 位整数(其中大约 400,000 个),它们在编译时都是已知的。
生产者创建 70 位整数 a,其中很多,非常快。
对于每个a,我需要确定是否存在来自v 的元素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 位 - 在
v[]上平均检查大约 20% 后,FOUND条件预计会得到满足。 - 可以在批量检查之前缓冲多个
a。 - 我不一定需要知道
v[]的哪个元素匹配,只要匹配或不匹配。 - 生成
a需要的内存非常少,因此上次调用遗留在L1 中的任何内容都可能仍然存在。
生成的代码旨在在支持 SSE4.2、AVX 指令的最新一代英特尔至强处理器上运行。 我很乐意接受使用英特尔 C 编译器或至少 GCC 编译的程序集或 C。
【问题讨论】:
-
如果你所做的只是一个简单的 AND'ing 操作,瓶颈很可能在生产者代码中。将 70 位数据打包成比特流将比仅检查它们是否为零更昂贵。
-
另外,256 位整数运算在 AVX2 中。因此,您可能会混淆 256 位浮点按位指令,但它们的吞吐量低于 128 位整数按位指令。所以我怀疑强迫自己使用 256 位向量是否会有所帮助。
-
确保
v中没有多余的值。如果(v[i] & v[j]) == v[i],则不需要测试v[j]。 -
@ughoavgfhw 情况并非如此。
v[]是 100% 非冗余、不可压缩的。 -
这个问题已经在其他问题中讨论过:"efficiently find the first element matching a bit mask"。最有希望的是 wildplasser 的两个答案(一个很容易矢量化,另一个使用更优化的算法)。
标签: c optimization x86-64 sse vectorization