【问题标题】:Numba - nopython mode slower than object mode?Numba - nopython 模式比对象模式慢?
【发布时间】:2017-08-08 08:23:24
【问题描述】:

首先在这里使用 Numba。我读到 nopython 模式应该产生更快的代码,但是这个:

@jit(float64[:](int64[:], int64, float64), nopython=True)
def epsilon_bound(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

@jit(float64(float64, int64, float64), nopython=False)
def sim_bin(epsilon, sims, delta):
    k=10000
    s = np.random.binomial(k, epsilon, size=(sims,))
    print(nb.typeof(s))
    bound = epsilon_bound(s, k, delta)
    violations = np.greater(epsilon, bound)
    return np.sum(violations)/float(sims)

%%time
a = sim_bin(0.1, 1_000_000, 0.1)

运行得更快:

array(int64, 1d, C)
CPU times: user 66.7 ms, sys: 0 ns, total: 66.7 ms
Wall time: 65.7 ms

比这个:

@jit(float64[:](int64[:], int64, float64), nopython=True)
def epsilon_bound(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

@jit(float64(float64, int64, float64), nopython=True)
def sim_bin(epsilon, sims, delta):
    k=10000
    s = np.random.binomial(k, epsilon, size=(sims,))
    #print(nb.typeof(s))
    bound = epsilon_bound(s, k, delta)
    violations = np.greater(epsilon, bound)
    return np.sum(violations)/float(sims)

CPU times: user 4.94 s, sys: 8.02 ms, total: 4.95 s
Wall time: 4.93 s

运行 sim_bin.inspect_types() 表明第一个选项正在使用所有 pyobjects,而第二个选项正确推断所有类型。根据文档 (http://numba.pydata.org/numba-doc/0.31.0/glossary.html#term-nopython-mode),nopython 模式应该会产生更快的代码。 有谁知道发生了什么?一定有充分的理由,但我不熟悉使用 Numba。是因为我主要使用向量化的 numpy 函数吗?

谢谢!!

【问题讨论】:

  • 当我运行这两段代码时,我发现没有性​​能差异。不过,一般来说,您希望忽略第一次运行 numba jitting 函数的时间,因为它包括 jitting 时间(所以使用 %timeit 而不是 %time)。
  • @JoshAdel 通过提供签名,您可以预编译函数,因此不需要编译运行。我看不到这些调用之间的时间差,但我绝对可以看到 jitted np.random.binomial 和未jitted 之间的时间差。
  • 对不起,我忘了包括我使用的是哪个版本的 python 和 numba。它是 Linux 上的 python 3.6、numba 0.31、numpy 1.12。我将检查此回归是否已修复。感谢您的帮助。

标签: python numba


【解决方案1】:

该功能的一个主要瓶颈(至少对于 numba 0.31,Windows 10)似乎是np.random.binomial-call。当我测试它时:

@jit(nopython=True)
def nbbinom():
    return np.random.binomial(10000, 0.1, size=(1000000,))

nbbinom() # warmup
%timeit nbbinom()
# 1 loop, best of 3: 2.45 s per loop
%timeit np.random.binomial(10000, 0.1, size=(1000000,))
# 10 loops, best of 3: 23.1 ms per loop

但这可能取决于 numba 版本。 Numba(不幸的是)经常遭受(幸运的是)快速修复的性能回归。可能它只需要他们的错误跟踪器上的一个问题(如果尚未修复)。

但即便如此,您的代码仍包含大量矢量化操作。如果您使用矢量化操作,您将不会通过 numba 获得太多的速度提升。根据经验:如果您已经可以在不使用 python 循环的情况下使用 numpy 进行操作,则不需要 numba(也有例外。例如:我发现 numba 对于小型数组来说确实更快,其中numpy-ufunc 的开销很大)。

另一件事是创建随机数组比实际操作花费更长的时间(在 numpy 和 numba 中):

import numpy as np
from numba import njit

@njit
def epsilon_bound1(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

def epsilon_bound2(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

def sim_bin(s, k, epsilon, sims, delta, func):
    bound = func(s, k, delta)
    violations = np.greater(epsilon, bound)
    return np.sum(violations)/float(sims)

epsilon = 0.1
sims = 1000000
delta = 0.1
k=10000
s = np.random.binomial(k, epsilon, size=(sims,))
%timeit np.random.binomial(k, epsilon, size=(sims,))
# 1 loop, best of 3: 232 ms per loop

sim_bin(s, k, 0.1, 1000000, 0.1, epsilon_bound1)  # warmup
%timeit sim_bin(s, k, 0.1, 1000000, 0.1, epsilon_bound1)
# 10 loops, best of 3: 28.5 ms per loop
%timeit sim_bin(s, k, 0.1, 1000000, 0.1, epsilon_bound2)
# 10 loops, best of 3: 37.6 ms per loop

因此,当您对 sim_bin 进行基准测试时,您实际上只对对 np.random.binomial 的调用进行基准测试,无论是相对快速的 numpy 还是(当前)相当慢的 numba 实现。

【讨论】:

  • 非常感谢!我不知道 numba 重新实现了 random.binomial。我怀疑我不会得到太多的加速,但当我看到它运行得更慢时,我感到非常失望。既然我知道它不应该发生,我会把它作为一个错误发布。
  • 我尝试在 epsilon_bound 上使用矢量化而不是 jit,但结果慢了 50%。您会说这些性能差异是可以预测的(一旦人们了解幕后发生的事情)还是需要反复试验?
  • 我在 numba 0.26 和 0.25 中测试了您的 nbbinom 比较,性能比您在 0.31 中看到的 random.binomial 慢。我猜这不是回归,只是一个较慢的实现。我也尝试了 v0.21 和 v0.23,但它无法运行。
  • @Luk17 关于可预测性:numba 不太可能比 numpy 做得更好。仅仅是因为如果它可以更快(并行执行除外),那么 numpy 可能也会使用更快的方式。但是,当您遇到 numpy 并尝试使用 python-loops 时,可能应该使用 cython/numba。但是,无法预测像np.random.binomial 这样的东西,这是一个出乎意料的性能不佳的功能。 :)
猜你喜欢
  • 2020-06-15
  • 2017-05-24
  • 2020-05-09
  • 1970-01-01
  • 2019-08-15
  • 2020-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多