# 1.14。线程层
> 原文: [http://numba.pydata.org/numba-doc/latest/user/threading-layer.html](http://numba.pydata.org/numba-doc/latest/user/threading-layer.html)
本节是关于 Numba 线程层,这是在内部用于执行通过使用 CPU 的`parallel`目标而发生的并行执行的库,即:
* 在`@jit`和`@njit`中使用`parallel=True` kwarg。
* 在`@vectorize`和`@guvectorize`中使用`target='parallel'` kwarg。
注意
如果代码库不使用`threading`或`multiprocessing`模块(或任何其他类型的并行),Numba 附带的线程层的默认值将运行良好,无需进一步操作!
## 1.14.1。哪些线程层可用?
有三个可用的线程层,它们的名称如下:
* `tbb` - 由英特尔 TBB 支持的线程层。
* `omp` - 由 OpenMP 支持的线程层。
* `workqueue` - 一个简单的内置工作共享任务调度程序。
实际上,保证存在的唯一螺纹层是`workqueue`。 `omp`层需要存在合适的 OpenMP 运行时库。 `tbb`层需要存在 Intel 的 TBB 库,这些库可以通过 conda 命令获得:
```py
$ conda install tbb
```
如果您使用`pip`安装 Numba,可以通过运行以下命令启用 TBB:
```py
$ pip install tbb
```
由于 manylinux1 的兼容性问题和其他可移植性问题,在 PyPI 上的 Numba 二进制轮中禁用了 OpenMP 线程层。
注意
Numba 搜索并加载线程层的默认方式是容忍缺少库,不兼容的运行时等。
## 1.14.2。设置穿线层
通过环境变量`NUMBA_THREADING_LAYER`或通过赋值给`numba.config.THREADING_LAYER`设置线程层。如果使用设置线程层的编程方法,则必须在逻辑上在发生并行目标的任何基于 Numba 的编译之前进行。选择线程层有两种方法,第一种是选择在各种形式的并行执行下安全的线程层,第二种是通过线程层名称进行显式选择(例如`tbb`)。
### 1.14.2.1。选择安全并行执行的线程层
并行执行从根本上以四种形式从核心 Python 库派生(前三个也适用于通过其他方式使用并行执行的代码!):
* 来自`threading`模块的`threads`。
* 来自`multiprocessing`模块`spawn`的`spawn`进程(Windows 上的默认值,仅适用于 Unix 上的 Python 3.4+)
* `fork`来自`multiprocessing`模块的进程通过`fork`(在 Unix 上是默认的,也是 Unix 上 Python 2 的唯一选项)。
* `fork`来自`multiprocessing`模块的进程通过使用`forkserver`(仅在 Unix 上的 Python 3 中可用)。基本上产生了一个新的过程,然后根据要求从这个新过程中生成叉子。
任何与这些形式的并行性一起使用的库必须在给定范例下表现出安全行为。因此,线程层选择方法旨在提供一种方法,以简单,跨平台和环境容忍的方式选择对给定范例安全的线程层库。可以提供给[设置机制](#numba-threading-layer-setting-mech)的选项如下:
* `default`没有提供特定的安全保证,是默认设置。
* `safe`是分叉和线程安全的,这需要安装`tbb`软件包(Intel TBB 库)。
* `forksafe`提供了一个 fork 安全库。
* `threadsafe`提供了一个线程安全的库。
要发现所选的线程层,可以在并行执行后调用函数`numba.threading_layer()`。例如,在没有安装 TBB 的 Linux 机器上:
```py
from numba import config, njit, threading_layer
import numpy as np
# set the threading layer before any parallel target compilation
config.THREADING_LAYER = 'threadsafe'
@njit(parallel=True)
def foo(a, b):
return a + b
x = np.arange(10.)
y = x.copy()
# this will force the compilation of the function, select a threading layer
# and then execute in parallel
foo(x, y)
# demonstrate the threading layer chosen
print("Threading layer chosen: %s" % threading_layer())
```
产生:
```py
Threading layer chosen: omp
```
这是有道理的,因为在 Linux 上存在的 GNU OpenMP 是线程安全的。
### 1.14.2.2。选择命名的线程层
高级用户可能希望为其用例选择特定的线程层,这可以通过直接向[设置机制](#numba-threading-layer-setting-mech)提供线程层名称来完成。选项和要求如下:
| 线程层名称 | 平台 | 要求 |
| --- | --- | --- |
| `tbb` | 所有 | `tbb`包(`$ conda install tbb`) |
| `omp` | Linux 的视窗 OSX | GNU OpenMP 库(很可能已经存在)MS OpenMP 库(很可能已经存在)`intel-openmp`包(`$ conda install intel-openmp`) |
| `workqueue` | 所有 | 没有 |
如果线程层未正确加载,Numba 将检测到这一点,并提供有关如何解决问题的提示。还应注意,Numba 诊断命令`numba -s`有一个`__Threading Layer Information__`部分,用于报告当前环境中线程层的可用性。
## 1.14.3。额外说明
线程层与 CPython 内部和系统级库的交互相当复杂,还需要注意一些其他事项:
* 英特尔 TBB 库的安装极大地拓宽了线程层选择过程中可用的选项。
* 在 Linux 上,`omp`线程层不是 fork 安全的,因为 GNU OpenMP 运行时库(`libgomp`)不是 fork 安全的。如果在使用`omp`线程层的程序中发生 fork,则会出现一种检测机制,它将尝试并正常终止分叉子项并将错误消息打印到`STDERR`。
* 在 OSX 上,需要`intel-openmp`包来启用基于 OpenMP 的线程层。
* 对于运行 Python 2.7 的 Windows 用户,`tbb`线程层不可用。
- 1. 用户手册
- 1.1。 Numba 的约 5 分钟指南
- 1.2。概述
- 1.3。安装
- 1.4。使用@jit 编译 Python 代码
- 1.5。使用@generated_jit 进行灵活的专业化
- 1.6。创建 Numpy 通用函数
- 1.7。用@jitclass 编译 python 类
- 1.8。使用@cfunc 创建 C 回调
- 1.9。提前编译代码
- 1.10。使用@jit 自动并行化
- 1.11。使用@stencil装饰器
- 1.12。从 JIT 代码 中回调到 Python 解释器
- 1.13。性能提示
- 1.14。线程层
- 1.15。故障排除和提示
- 1.16。常见问题
- 1.17。示例
- 1.18。会谈和教程
- 2. 参考手册
- 2.1。类型和签名
- 2.2。即时编译
- 2.3。提前编译
- 2.4。公用事业
- 2.5。环境变量
- 2.6。支持的 Python 功能
- 2.7。支持的 NumPy 功能
- 2.8。与 Python 语义的偏差
- 2.9。浮点陷阱
- 2.10。 Python 2.7 寿命终止计划
- 3. 用于 CUDA GPU 的 Numba
- 3.1。概述
- 3.2。编写 CUDA 内核
- 3.3。内存管理
- 3.4。编写设备功能
- 3.5。 CUDA Python 中支持的 Python 功能
- 3.6。支持的原子操作
- 3.7。随机数生成
- 3.8。设备管理
- 3.10。示例
- 3.11。使用 CUDA 模拟器 调试 CUDA Python
- 3.12。 GPU 减少
- 3.13。 CUDA Ufuncs 和广义 Ufuncs
- 3.14。共享 CUDA 内存
- 3.15。 CUDA 阵列接口
- 3.16。 CUDA 常见问题
- 4. CUDA Python 参考
- 4.1。 CUDA 主机 API
- 4.2。 CUDA 内核 API
- 4.3。内存管理
- 5. 用于 AMD ROC GPU 的 Numba
- 5.1。概述
- 5.2。编写 HSA 内核
- 5.3。内存管理
- 5.4。编写设备功能
- 5.5。支持的原子操作
- 5.6。代理商
- 5.7。 ROC Ufuncs 和广义 Ufuncs
- 5.8。示例
- 6. 扩展 Numba
- 6.1。高级扩展 API
- 6.2。低级扩展 API
- 6.3。示例:间隔类型
- 7. 开发者手册
- 7.1。贡献给 Numba
- 7.2。 Numba 建筑
- 7.3。多态调度
- 7.4。关于发电机的注意事项
- 7.5。关于 Numba Runtime 的注意事项
- 7.6。使用 Numba Rewrite Pass 获得乐趣和优化
- 7.7。实时变量分析
- 7.8。上市
- 7.9。模板注释
- 7.10。关于自定义管道的注意事项
- 7.11。环境对象
- 7.12。哈希 的注意事项
- 7.13。 Numba 项目路线图
- 8. Numba 增强建议
- 9. 术语表