# 7.5。关于 Numba Runtime 的注意事项
> 原文: [http://numba.pydata.org/numba-doc/latest/developer/numba-runtime.html](http://numba.pydata.org/numba-doc/latest/developer/numba-runtime.html)
_Numba Runtime(NRT)_ 为 _nopython 模式 _ Python 子集提供语言运行时。 NRT 是一个带有 Python 绑定的独立 C 库。这允许在没有 GIL 的情况下使用 NPM 运行时功能。目前,NRT 中实现的唯一语言功能是内存管理。
## 7.5.1。内存管理
NRT 实现 NPM 代码的内存管理。它使用 _ 原子引用计数 _ 进行线程安全的确定性内存管理。 NRT 维护一个单独的`MemInfo`结构,用于存储有关每个分配的信息。
### 7.5.1.1。与 CPython 合作
为了让 NRT 与 CPython 合作,NRT python 绑定提供了用于转换导出内存区域的 python 对象的适配器。当这样的对象用作 NPM 函数的参数时,会创建一个新的`MemInfo`并获取对 Python 对象的引用。当 NPM 值返回到 Python 解释器时,将检查关联的`MemInfo`(如果有)。如果`MemInfo`引用 Python 对象,则会释放并返回基础 Python 对象。否则,`MemInfo`将包装在 Python 对象中并返回。根据类型,可能需要额外的过程。
当前实现支持 Numpy 数组和任何缓冲区导出类型。
### 7.5.1.2。编译器方面的合作
NRT 引用计数要求编译器根据用法发出递增/递减操作。当引用计数降为零时,编译器必须在 NRT 中调用析构函数例程。
### 7.5.1.3。优化
允许编译器天真地发出递增/递减操作。它依赖于优化传递来删除冗余引用计数操作。
优化过程在块级别上运行以避免控制流分析。它取决于 LLVM 函数优化传递,以简化控制流,堆栈到寄存器和简化指令。它的工作原理是匹配和删除每个块中的 incrementf 和 decref 对。
### 7.5.1.4。怪癖
由于[引用计数优化传递](#nrt-refct-opt-pass)需要 LLVM 函数优化传递,因此传递在 LLVM IR 上作为文本工作。然后,优化的 IR 再次实现为新的 LLVM 内存中 bitcode 对象。
### 7.5.1.5。调试泄漏
要调试 NRT MemInfo 中的引用泄漏,每个 MemInfo python 对象都有一个`.refcount`属性用于检查。要从 NRT 分配的 ndarray 获取 MemInfo,请使用`.base`属性。
要调试 NRT 中的内存泄漏,`numba.runtime.rtsys`定义`.get_allocation_stats()`。它返回一个 namedtuple,它包含自程序启动以来的分配和释放次数。检查分配和释放计数器是否匹配是了解 NRT 是否泄漏的最简单方法。
### 7.5.1.6。调试 C 中的泄漏
[numba / runtime / nrt.h](https://github.com/numba/numba/blob/master/numba/runtime/nrt.h) 的开头有以下几行:
```py
/* Debugging facilities - enabled at compile-time */
/* #undef NDEBUG */
#if 0
# define NRT_Debug(X) X
#else
# define NRT_Debug(X) if (0) { X; }
#endif
```
取消定义 NDEBUG(取消注释`#undef NDEBUG`行)可以在 NRT 中启用断言检查。
启用 NRT_Debug(用`#if 1`替换`#if 0`)将打开 NRT 内的调试打印。
## 7.5.2。递归支持
在编译一对相互递归函数期间,其中一个函数将包含未解析的符号引用,因为编译器一次处理一个函数。在 LLVM 生成机器代码之前,未分解符号的存储器被分配并初始化为 _ 未解析符号中止 _ 函数(`nrt_unresolved_abort`)的地址。在编译新函数时跟踪和解析这些符号。如果错误阻止了这些符号的解析,则将调用中止函数,从而引发`RuntimeError`异常。
_ 未解析符号中止 _ 函数在 NRT 中定义为零参数签名。调用者可以安全地使用任意数量的参数调用它。因此,可以安全地用于预定的被叫者。
## 7.5.3。未来计划
NRT 的计划是创建一个可以链接到 Numba 编译代码的独立共享库,包括在 Python 解释器中使用而不需要 Python 解释器。为了做到这一点,我们将进行一些重构:
* numba NPM 代码引用“helperlib.c”中的静态编译代码。这些功能应该转移到 NRT。
- 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. 术语表