所以我需要改进我一直在处理的脚本的执行时间。我开始使用numba jit decorator来尝试并行计算,但它却抛弃了我
KeyError: "Does not support option: 'parallel'"
所以我决定测试nogil,如果它解锁了我的cpu的整个功能,但它比纯python慢,我不明白为什么会发生这种情况,如果有人可以帮助我或指导我,我将非常感激
import numpy as np
from numba import *
@jit(['float64[:,:],float64[:,:]'],'(n,m),(n,m)->(n,m)',nogil=True)
def asd(x,y):
return x+y
u=np.random.random(100)
w=np.random.random(100)
%timeit asd(u,w)
%timeit u+w
10000次循环,最佳为3:每循环137μs 最慢的运行时间比最快的运行时长7.13倍。这可能意味着正在缓存中间结果 1000000次循环,最佳3:每循环1.75μs
答案 0 :(得分:4)
你不能指望numba在这么简单的矢量化操作上胜过numpy。你的比较也不完全公平,因为numba函数包括外部函数调用的成本。如果你对一个更大的数组求和,你会发现两个收敛的性能和你所看到的只是在一个非常快的操作上的开销:
import numpy as np
import numba as nb
@nb.njit
def asd(x,y):
return x+y
def asd2(x, y):
return x + y
u=np.random.random(10000)
w=np.random.random(10000)
%timeit asd(u,w)
%timeit asd2(u,w)
The slowest run took 17796.43 times longer than the fastest. This could mean
that an intermediate result is being cached.
100000 loops, best of 3: 6.06 µs per loop
The slowest run took 29.94 times longer than the fastest. This could mean that
an intermediate result is being cached.
100000 loops, best of 3: 5.11 µs per loop
就并行功能而言,对于这个简单的操作,您可以使用nb.vectorize
:
@nb.vectorize([nb.float64(nb.float64, nb.float64)], target='parallel')
def asd3(x, y):
return x + y
u=np.random.random((100000, 10))
w=np.random.random((100000, 10))
%timeit asd(u,w)
%timeit asd2(u,w)
%timeit asd3(u,w)
但是,如果你在小型数组上运行,你将会看到线程调度的开销。对于上面的阵列大小,我看到并行给了我2倍的加速。
numba真正闪耀的地方是使用广播进行numpy难以进行的操作,或者当操作会导致大量临时中间阵列分配时。