ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 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`线程层不可用。