Numba np.convolve 真的很慢

互联网 行业动态 更新时间:2024-06-13 00:19:06

Jér*_*ard 8

问题来自np.convolve. 这是一个已知问题。事实证明,当前的 Numba 实现比 Numpy 的实现要慢得多 (在 Windows 上测试的版本 <=0.54.1)。


在引擎盖下

一方面,Numpy 实现调用correlate本身执行一个点积,应该由系统上可用的快速 BLAS 库实现。另一方面,使用它的Numba实现调用_get_inner_prod应该使用相同的 BLAS 库(假设检测到 BLAS 应该是这种情况)......np.dot

话虽如此,与点积相关的问题有很多:

首先,如果内部变量_HAVE_BLASofnumba/np/arraymath.py被手动禁用,Numba 会使用点积的后备实现,它应该会显着变慢。然而,事实证明,使用 by 使用的后备点积实现np.convolve比在我的机器上使用 BLAS 包装器的执行速度快 5 倍!fastmath=True另外使用 Numba 装饰器中的参数njit会导致整体执行速度提高 8.7 倍!这是测试代码:

import numpy as np
import numba as nb

def npConvolve(a, b):
    return np.convolve(a, b)

@nb.njit('float64[:](float64[:], float64[:])')
def nbConvolveUncont(a, b):
    return np.convolve(a, b)

@nb.njit('float64[::1](float64[::1], float64[::1])')
def nbConvolveCont(a, b):
    return np.convolve(a, b)

a = np.random.random(6400)
b = np.random.random(65)
%timeit -n 100 npConvolve(a, b)
%timeit -n 100 nbConvolveUncont(a, b)
%timeit -n 100 nbConvolveCont(a, b)

以下是原始有趣的结果:

With _HAVE_BLAS=True (default):
126 µs ± 292 ns per loop
1.6 ms ± 21.3 µs per loop
1.6 ms ± 18.5 µs per loop

With _HAVE_BLAS=False:
125 µs ± 359 ns per loop
311 µs ± 1.18 µs per loop
268 µs ± 4.26 µs per loop

With _HAVE_BLAS=False and fastmath=True:
125 µs ± 757 ns per loop
327 µs ± 3.69 µs per loop
183 µs ± 654 ns per loop

此外,np_convolveNumba 在内部翻转一些数组参数,然后使用具有非平凡步幅(即非 1)的翻转数组执行点积。这种不平凡的步幅可能会对点积性能产生影响。更一般地说,任何阻止编译器知道数组是连续的转换肯定会强烈影响性能。实际上,以下测试显示了使用 Numba 的点积实现处理连续数组的影响:

import numpy as np
import numba as nb

def np_dot(a, b):
    return np.dot(a, b)

@nb.njit('float64(float64[::1], float64[::1])')
def nb_dot_cont(a, b):
    return np.dot(a, b)

@nb.njit('float64(float64[::1], float64[:])')
def nb_dot_stride(a, b):
    return np.dot(a, b)

v = np.random.random(128*1024)
%timeit -n 200 np_dot(v, v)         #  36.5 µs ±  4.9 µs per loop
%timeit -n 200 nb_dot_stride(v, v)  # 361.0 µs ± 17.1 µs per loop  (x10 !!!)
%timeit -n 200 nb_dot_cont(v, v)    #  34.1 µs ±  2.9 µs per loop

关于 Numpy 和 Numba 的一些一般说明

请注意,Numba 在处理非常大的数组时几乎无法加速 Numpy 调用,因为 Numba主要在 Python 中重新实现 Numpy 函数并使用JIT 编译器(LLVM-Lite) 来加速它们,而 Numpy 主要以普通方式实现 - C(带有相当慢的 Python 包装代码)。Numpy 代码使用SIMD 指令等低级处理器特性来加速许多函数的执行。两者似乎都使用已知高度优化的 BLAS 库。由于 Numpy 目前比 Numba 更成熟,因此 Numpy 通常会更加优化:Numpy 有更多的贡献者工作时间更长。

更多推荐

真的很,Numba,np,convolve

本文发布于:2023-04-20 20:35:28,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:真的很   Numba   np   convolve

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!