提交 eb45cab7 编写于 作者: Y yanbohan

Revision 1.1

上级 70b3e52e
# 1.1。 Numba 的约 5 分钟指南
# 1.1. Numba 的 ~ 5 分钟指南
> 原文: [http://numba.pydata.org/numba-doc/latest/user/5minguide.html](http://numba.pydata.org/numba-doc/latest/user/5minguide.html)
Numba 是 Python 的即时编译器,它最适用于使用 NumPy 数组和函数以及循环的代码。使用 Numba 的最常用方法是通过其装饰器集合,可以应用于您的函数来指示 Numba 编译它们。当调用 Numba 修饰函数时,它被编译为机器代码“及时”执行,并且您的全部或部分代码随后可以以本机机器代码速度运行!
Numba 是 Python 的即时(JIT)编译器,它最适用于使用 NumPy 数组、函数和循环的代码。使用 Numba 的最常用方法是使用其装饰器集合,通过作用于您的函数来指示 Numba 编译它们。当调用 Numba 修饰函数时,它被编译为机器代码“即时”(JIT)执行,从而使您的全部或部分代码随后可以以本机机器代码速度运行!
开箱即用的 Numba 使用以下方法
Numba 可直接运行于下列环境
* 操作系统:Windows(32 位和 64 位),OSX 和 Linux(32 位和 64 位)
* 架构:x86,x86_64,ppc64le。在 armv7l,armv8l(aarch64)上进行实验。
* GPU:Nvidia CUDA。 AMD ROC 的实验
* CPython
* NumPy 1.10 - 最新
* GPU:Nvidia CUDA。 在 AMD ROC 上的应用是实验性质的
* CPython
* NumPy 1.10 - 最新
## 1.1.1。我怎么得到它
## 1.1.1. 如何获取Numba
Numba 可用作 [Anaconda Python 发行版](https://www.anaconda.com/) [conda](https://conda.io/docs/) 软件包:
Numba [Anaconda Python 发行版](https://www.anaconda.com/)的一个 [conda](https://conda.io/docs/) 软件包:
```py
$ conda install numba
```
Numba 还有轮子可供选择:
Numba 还有wheels(.whl)可供选择:
```py
$ pip install numba
```
Numba 也可以从源编译[,虽然我们不建议首次使用 Numba 用户。](installing.html#numba-source-install-instructions)
Numba 也可以从[源码](installing.html#numba-source-install-instructions) (校对注:md超链接需要整体修改) 编译,但我们不建议首次使用 Numba 的用户使用这种方法。
Numba 通常用作核心包,因此其依赖性保持在绝对最小值,但是,可以按如下方式安装额外的包以提供其他功能:
Numba 通常用作核心包,因此其依赖性被尽可能减小,但可以额外安装下列包以提供附加功能:
* `scipy` - 支持编译`numpy.linalg`功能
* `scipy` - 支持编译 `numpy.linalg` 的函数
* `colorama` - 支持回溯/错误消息中的颜色突出显示。
* `pyyaml` - 通过 YAML 配置文件启用 Numba 配置
* `icc_rt` - 允许使用 Intel SVML(高性能短矢量数学库,仅限 x86_64)。安装说明在[性能提示](performance-tips.html#intel-svml)中。
* `pyyaml` - 启用 Numba 配置的 YAML 配置文件
* `icc_rt` - 允许使用 Intel SVML(高性能短矢量数学库,仅限 x86_64 架构)。安装说明在[性能提示](performance-tips.html#intel-svml) (校对注:md超链接需要整体修改) 中。
## 1.1.2。 Numba 会为我的代码工作吗?
## 1.1.2. Numba 会对我的代码有用吗?
这取决于你的代码是什么样的,如果你的代码是以数字为导向的(做很多数学运算),使用 NumPy 和/或有很多循环,那么 Numba 通常是一个不错的选择。在这些例子中,我们将应用最基本的 Numba 的 JIT 装饰器`@jit`来尝试加速某些功能,以证明哪些功能正常,哪些功能不正常
这取决于你的代码是什么样的,如果你的代码是以数字为导向的(做很多数学运算),使用 NumPy 和/或有很多循环,那么 Numba 通常是一个不错的选择。在以下的例子中,我们将应用最基本的 Numba 的 JIT 装饰器`@jit`来尝试加速某些函数,以展示哪些函数会被改善,哪些函数不能被改善
Numba 代码看起来像这样:
Numba 可以改善的代码看起来像这样:
```py
from numba import jit
......@@ -49,18 +49,18 @@ import numpy as np
x = np.arange(100).reshape(10, 10)
@jit(nopython=True) # Set "nopython" mode for best performance, equivalent to @njit
def go_fast(a): # Function is compiled to machine code when called the first time
@jit(nopython=True) # 使用 "nopython" 模式以提供更好的性能, 等价于 @njit
def go_fast(a): # 当函数第一次被调用时会被编译为机器码
trace = 0
for i in range(a.shape[0]): # Numba likes loops
trace += np.tanh(a[i, i]) # Numba likes NumPy functions
return a + trace # Numba likes NumPy broadcasting
for i in range(a.shape[0]): # Numba 偏好循环
trace += np.tanh(a[i, i]) # Numba 偏好 NumPy 函数
return a + trace # Numba 偏好 NumPy 广播(broadcasting)
print(go_fast(x))
```
对于看起来像这样的代码,如果有的话,它将无法正常工作:
对于这样的代码(如果有的话)Numba将无法很好地工作:
```py
from numba import jit
......@@ -69,28 +69,28 @@ import pandas as pd
x = {'a': [1, 2, 3], 'b': [20, 30, 40]}
@jit
def use_pandas(a): # Function will not benefit from Numba jit
df = pd.DataFrame.from_dict(a) # Numba doesn't know about pd.DataFrame
df += 1 # Numba doesn't understand what this is
return df.cov() # or this!
def use_pandas(a): # 这个函数无法受益于 Numba jit
df = pd.DataFrame.from_dict(a) # Numba 不识别 pd.DataFrame
df += 1 # Numba 不明白这是什么
return df.cov() # 或是这个
print(use_pandas(x))
```
请注意,Numba 不理解 Pandas,因此 Numba 只是通过解释器运行此代码,但增加了 Numba 内部开销的成本!
请注意,Numba 不识别 Pandas,因此 Numba 只是通过解释器运行此代码,却增加了 Numba 内部开销的成本!
## 1.1.3什么是`nopython`模式?
## 1.1.3. 什么是`nopython`模式?
Numba `@jit`装饰器基本上以两种编译模式运行,`nopython`模式和`object`模式。在上面的`go_fast`示例中,`@jit``@jit`装饰器中设置,这是指示 Numba 在`nopython`模式下运行。 `nopython`编译模式的行为本质上是编译装饰函数,以便它完全运行而不需要 Python 解释器的参与。这是使用 Numba `jit`装饰器的推荐和最佳实践方式,因为它可以获得最佳性能。
Numba `@jit`装饰器基本上以两种编译模式运行,`nopython`模式和`object`模式。在上面的`go_fast`示例中,`@jit`装饰器中设置了`nopython=True`,这是指示 Numba 在`nopython`模式下运行。 `nopython`编译模式的行为本质上是编译装饰函数,以便它完全运行而不需要 Python 解释器的参与。这是使用 Numba `jit`装饰器的推荐和最佳实践方式,因为它可以获得最佳性能。
如果`nopython`模式下的编译失败,Numba 可以使用`object mode`进行编译,如果未设置`nopython=True`,这是`@jit`装饰器的后退模式(如上面的`use_pandas`示例所示)。在这种模式下,Numba 将识别它可以编译的循环,并将它们编译成在机器代码中运行的函数,并且它将运行解释器中的其余代码。为获得最佳性能,请避免使用此模式
如果`nopython`模式下的编译失败,Numba 可以使用`object mode`进行编译,如果未设置`nopython=True`,这是`@jit`装饰器的降级模式(如上面的`use_pandas`示例所示)。在这种模式下,Numba 将识别它可以编译的循环,并将它们编译成在机器代码中运行的函数,并且它将运行解释器中的其余代码。为获得最佳性能,请避免使用此模式!
## 1.1.4如何衡量 Numba 的表现?
## 1.1.4. 如何衡量 Numba 的表现?
首先,回想一下 Numba 必须为执行函数的机器代码版本之前给出的参数类型编译函数,这需要时间。但是,一旦编译完成,Numba 会为所呈现的特定类型的参数缓存函数的机器代码版本。如果再次使用相同类型调用它,它可以重用缓存版本而不必再次编译。
首先,回想一下 Numba 必须在执行函数的机器代码版本之前对于你的包含特定参数的函数进行编译,这需要时间。但是,一旦编译完成,Numba 会为所特定类型的参数缓存函数的机器代码版本。如果再次使用相同类型调用它,它可以重用缓存版本而不必再次编译。
测量性能时,一个非常常见的错误是不考虑上述行为,并使用一个简单的计时器对时间进行一次编码,该计时器包括在执行时编译函数所需的时间。
测量性能时,一个非常常见的错误是不考虑上述行为,并使用一个简单的计时器对时间进行一次编码,该计时器包括在执行时编译函数所需的时间。
例如:
......@@ -122,7 +122,7 @@ print("Elapsed (after compilation) = %s" % (end - start))
```
这,例如打印
如此会打印(举例)
```py
Elapsed (with compilation) = 0.33030009269714355
......@@ -132,39 +132,39 @@ Elapsed (after compilation) = 6.67572021484375e-06
衡量 Numba JIT 对您的代码的影响的一个好方法是使用 [timeit](https://docs.python.org/3/library/timeit.html) 模块函数来执行时间,这些函数测量多次执行迭代,因此可以适应编译时间在第一次执行。
另外,如果编译时间成问题,Numba JIT 支持已编译函数的[磁盘缓存](../reference/jit-compilation.html#jit-decorator-cache),并且还具有 [Ahead-Of-Time](../reference/aot-compilation.html#aot-compilation) 编译模式。
另外,如果编译时间是一个问题,Numba JIT 支持已编译函数的[磁盘缓存](../reference/jit-compilation.html#jit-decorator-cache) (校对注:md超链接需要整体修改) ,并且还具有 [Ahead-Of-Time](../reference/aot-compilation.html#aot-compilation) (校对注:md超链接需要整体修改) 编译模式。
## 1.1.5。它有多快?
## 1.1.5. Numba有多快?
假设 Numba 可以在`nopython`模式下运行,或者至少编译一些循环,它将针对您的特定 CPU 进行编译。加速因应用而异,但可以是一到两个数量级。 Numba 有一个[性能指南](performance-tips.html#performance-tips),涵盖了获得额外性能的常用选项。
假设 Numba 可以在`nopython`模式下运行,或者至少编译一些循环,它将针对您的特定 CPU 进行编译。加速因应用而异,但可以是一到两个数量级。 Numba 有一个[性能指南](performance-tips.html#performance-tips) (校对注:md超链接需要整体修改) ,涵盖了获得额外性能的常用选项。
## 1.1.6。 Numba 如何运作?
## 1.1.6. Numba 如何工作?
Numba 读取装饰函数的 Python 字节码,并将其与有关函数输入参数类型的信息相结合。它分析并优化您的代码,最后使用 LLVM 编译器库生成函数的机器代码版本,根据您的 CPU 功能量身定制。每次调用函数时都会使用此编译版本。
Numba 读取被装饰函数的 Python 字节码,并将其与有关函数输入参数类型的信息相结合。Numba会分析并优化您的代码,最后使用 LLVM 编译器库生成函数的机器代码版本,这将针对您的 CPU 功能量身定制。此后每次调用函数时都会使用此编译版本。
## 1.1.7。其他感兴趣的东西:
## 1.1.7. 其他有意义的东西:
Numba 有很多装饰,我们见过`@jit`,但也有:
Numba 有很多装饰,我们见过`@jit`,但也有:
* `@njit` - 这是`@jit(nopython=True)`的别名,因为它是如此常用!
* `@vectorize` - 产生 NumPy `ufunc`(支持所有`ufunc`方法)。 [文件在这里](vectorize.html#vectorize)
* `@guvectorize` - 产生 NumPy 广义`ufunc`[文件在这里](vectorize.html#guvectorize)
* `@stencil` - 将函数声明为类似模板操作的内核。 [文件在这里](stencil.html#numba-stencil)
* `@jitclass` - 用于 jit 感知类。 [文件在这里](jitclass.html#jitclass)
* `@cfunc` - 声明一个用作本机回调的函数(从 C / C ++等调用)。 [文件在这里](cfunc.html#cfunc)
* `@overload` - 注册您自己的函数实现,以便在 nopython 模式下使用,例如: `@overload(scipy.special.j0)`[文件在这里](../extending/high-level.html#high-level-extending)
* `@njit` - 这是`@jit(nopython=True)`的别名,因为它非常常用!
* `@vectorize` - 产生 NumPy `ufunc`(支持所有`ufunc`方法)。 [文件在这里](vectorize.html#vectorize) (校对注:md超链接需要整体修改)
* `@guvectorize` - 产生 NumPy 广义`ufunc`[文件在这里](vectorize.html#guvectorize) (校对注:md超链接需要整体修改)
* `@stencil` - 将函数声明为类似模板操作的内核。 [文件在这里](stencil.html#numba-stencil) (校对注:md超链接需要整体修改)
* `@jitclass` - 用于 jit 感知类。 [文件在这里](jitclass.html#jitclass) (校对注:md超链接需要整体修改)
* `@cfunc` - 声明一个用作本机回调的函数(从 C / C ++等调用)。 [文件在这里](cfunc.html#cfunc) (校对注:md超链接需要整体修改)
* `@overload` - 注册您自己的函数实现,以便在 nopython 模式下使用,例如: `@overload(scipy.special.j0)`[文件在这里](../extending/high-level.html#high-level-extending) (校对注:md超链接需要整体修改)
一些装饰提供额外选项:
一些装饰提供额外选项:
* `parallel = True` - [使能](../reference/jit-compilation.html#jit-decorator-parallel)功能的[自动并行化](parallel.html#numba-parallel)
* `fastmath = True` - 为该功能启用 [fast-math](../reference/jit-compilation.html#jit-decorator-fastmath) 行为
* `parallel = True` - [开启](../reference/jit-compilation.html#jit-decorator-parallel)(校对注:md超链接需要整体修改)函数的[自动并行化](parallel.html#numba-parallel)(校对注:md超链接需要整体修改)
* `fastmath = True` - 为该函数启用 [fast-math](../reference/jit-compilation.html#jit-decorator-fastmath) (校对注:md超链接需要整体修改) 表现
ctypes / cffi / cython 互操作性:
ctypes / cffi / cython 互性:
* `cffi` - `nopython`模式支持调用 [CFFI](../reference/pysupported.html#cffi-support) 功能。
* `ctypes` - `nopython`模式支持调用 [ctypes](../reference/pysupported.html#ctypes-support) 包装函数。 。
* Cython 导出函数[可调用](../extending/high-level.html#cython-support)
* `cffi` - `nopython`模式支持调用 [CFFI](../reference/pysupported.html#cffi-support) (校对注:md超链接需要整体修改)功能。
* `ctypes` - `nopython`模式支持调用 [ctypes](../reference/pysupported.html#ctypes-support) (校对注:md超链接需要整体修改) 包装函数。
* Cython 导出函数[可调用](../extending/high-level.html#cython-support)(校对注:md超链接需要整体修改)
### 1.1.7.1。 GPU 目标
### 1.1.7.1. 用于 GPU 目的
Numba 可以靶向 [Nvidia CUDA](https://developer.nvidia.com/cuda-zone) 和(实验性) [AMD ROC](https://rocm.github.io/) GPU。您可以用纯 Python 编写内核,让 Numba 处理计算和数据移动(或明确地执行此操作)。点击 [CUDA](../cuda/index.html#cuda-index)[ROC](../roc/index.html#roc-index) 的 Numba 文档。
\ No newline at end of file
Numba 可以面向 [Nvidia CUDA](https://developer.nvidia.com/cuda-zone)[AMD ROC](https://rocm.github.io/)(实验性的) GPU 进行程序设计。您可以用纯 Python 编写内核,让 Numba 处理计算和数据移动(或显式执行此操作)。参见 [CUDA](../cuda/index.html#cuda-index)(校对注:md超链接需要整体修改)[ROC](../roc/index.html#roc-index) (校对注:md超链接需要整体修改) 的 Numba 文档。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册