![](/img/trans.png)
[英]Fastest way to calculate Euclidean and Minkowski distance between all the vectors in a list of lists python
[英]Fastest way to calculate the Hamming distance between 2 binary vectors in Python / Cython / Numpy
我正在尝试计算二进制向量和二进制向量矩阵之间的汉明距离。 我能找到的最快方法是使用带有 Numpy 的无符号 8 位整数:
import numpy as np
np.count_nonzero(data[0] != data, axis=1)
但是,这种方法的问题在于它首先找到所有不同的位,然后对差异的数量求和。 这不是有点浪费吗? 我尝试在 C++ 中实现一个基本版本,其中我还计算了不同的位数,因此最后不需要总和,但这要慢得多。 可能是因为 Numpy 使用 SIMD 指令。
所以我的问题是。 有没有办法使用 Numpy / Python / Cython 中的 SIMD 指令直接计算汉明距离?
理想情况下,您实际上希望 CPU 做的是sum += popcount( a[i] ^ b[i])
和尽可能大的块。 例如,在 x86 上,使用 AVX2 对一条指令一次异或 32 个字节,然后再使用几条指令(包括 vpshufb 和 vpaddq)将计数累加到每个元素计数的 SIMD 向量中(最后水平求和)。
使用特定 ISA(如 x86-64)的 C++ 内在函数,这很容易。
您可以使用std::bitset<64>
对 64 位块进行异或运算,并将.count()
作为可移植的 API 来实现有效的 popcount。 Clang 可以将标量 popcount 自动矢量化为 AVX2,但 GCC 不能。
为了在不违反严格混叠的情况下安全地构造它,您可能需要将另一种类型的任意数据memcpy
转换为unsigned long long
。
我不知道 Numpy 是否有一个用于编译的循环,否则你可能需要在一个通道中进行异或,然后在另一个通道中进行 popcount,这会降低计算强度,所以你肯定想将它缓存块成小块在您返回重新读取它们之前,它们会在 L1d 缓存中保持热状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.