# 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. 術語表