【问题标题】:Why are numpy calculations not affected by the global interpreter lock?为什么 numpy 计算不受全局解释器锁的影响?
【发布时间】:2016-07-28 12:15:19
【问题描述】:

我正在尝试决定是否应该使用多处理或线程,并且我学到了一些关于Global Interpreter Lock 的有趣信息。在这个不错的blog post 中,多线程似乎不适合繁忙的任务。但是,我也了解到某些功能,例如 I/O 或 numpy,不受 GIL 的影响。

谁能解释为什么,以及我如何确定我的(可能是相当 numpy-heavy)代码是否适合多线程?

【问题讨论】:

    标签: python multithreading numpy multiprocessing gil


    【解决方案1】:

    许多 numpy 计算不受 GIL 影响,但不是全部。

    在不需要 Python 解释器的代码(例如 C 库)中,可以专门释放 GIL - 允许依赖于解释器的其他代码继续运行。在 Numpy C 代码库中,宏 NPY_BEGIN_THREADSNPY_END_THREADS 用于分隔允许 GIL 发布的代码块。你可以在this search of the numpy source看到这些。

    NumPy C API documentation 有更多关于线程支持的信息。请注意附加的宏 NPY_BEGIN_THREADS_DESCRNPY_END_THREADS_DESCRNPY_BEGIN_THREADS_THRESHOLDED,它们处理条件 GIL 释放,取决于数组 dtypes 和循环的大小。

    大多数核心函数都会发布 GIL - 例如 Universal Functions (ufunc) 这样做 as described

    只要不涉及对象数组,Python 全局解释器锁 (GIL) 就会在调用循环之前释放。必要时重新获取它以处理错误情况。

    关于您自己的代码,source code for NumPy is available。检查您为上述宏使用的函数(以及它们调用的函数)。另请注意,性能优势在很大程度上取决于多长时间 GIL 发布 - 如果您的代码不断地加入/退出 Python,您将不会看到太大的改进。

    另一种选择是测试它。但是,请记住,使用条件 GIL 宏的函数可能会针对小型和大型数组表现出不同的行为。因此,使用小数据集的测试可能无法准确表示大型任务的性能。

    有一些关于使用 numpy 进行并行处理的额外信息on the official wiki 和一篇关于 Python GIL 的有用帖子over on Programmers.SE

    【讨论】:

      猜你喜欢
      • 2011-09-06
      • 2010-09-20
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多