【问题标题】:Does cPython use multiple cores for built-in functions such as sort, any, all?cPython 是否对内置函数(如 sort、any、all)使用多个内核?
【发布时间】:2015-10-15 10:17:38
【问题描述】:

我了解 cPython 有一个 GIL,因此如果不使用多处理模块,您的脚本就无法在多个内核上运行。但是有什么可以阻止内置功能,例如使用多核排序吗?我不了解 cPython 结构,但我认为我要问的问题是'是内置函数,如排序、任何和列表推导实际上低于 GIL?

【问题讨论】:

    标签: python multiprocessing cpython python-internals


    【解决方案1】:

    cPython GIL 只允许单个线程在进程中运行字节码——它与非抽象 CPU 无关。

    也就是说,到目前为止,除非您调用某些东西来分叉/使用多个进程,或者您的操作系统/硬件正在捕获调用并为您执行此操作(极不可能),否则您将看到您的所有操作都发生在一个单一的CPU 内核。

    在 C 中实现的内置函数发生在“GIL 之下”,因为它们更直接地调用底层 API,但将参数和数据放入这些函数发生在 GIL 中,因为您使用字节码来读取然后写。

    顺便说一句,如果您想更好地了解 cPython 与其宿主的关系,我建议您使用以下high-level official overview 和/或the PDF slides and the playground that I wrote for a conference

    【讨论】:

    • GIL 不仅仅是字节码。引用计数也只能在 GIL 下更新,这意味着操纵引用计数的东西在这样做时根本无法释放 GIL。 anyallsorted 完全在 GIL 下运行,因为它们都发生了大量的引用计数操作,即使不一定要执行字节码(例如,在 sorted 的情况下,使用比较也在 C 层的内置类型)。已经有使用原子操作来维护 ref 计数的测试,它总是使 CPython 变慢,令人无法接受。
    • 我不确定我是否说过 GIL only 与字节码有关——我正在解决问题的重点是 Python 的“前端”——排序/任何/列表。将参数传递给那些发生在字节码中。
    • 你没有,但主要问题是阻止任何使用 sorted/any/all 释放 GIL(即使他们可以保证正在处理的项目永远不会执行用于比较、生成值、应用谓词等的字节码)。 OP 的问题是关于并行化能力和 GIL 限制,而不是什么是字节码,什么不是。内置函数位于字节码层之下,但它们并非没有 GIL,因为即使它们所做的工作可以保证永远不会执行字节码(它不能),甚至完全使用 Python 对象在 C 中编写代码需要 GIL。
    • 嗯...我可能误解了“低于 GIL”这个短语。当我听到“低于”时,我将其解释为“GIL 在 Python 中运行在高位,而“低于”意味着“不受 GIL 影响”。但是在非行话英语单词“under [the GIL]”中的其他同义词在线程行话中的意思是“持有 GIL”。因此,当您说“在 C 中实现的内置函数发生在 GIL 之下”时,我听到的是“内置 C 函数释放了允许并行性的 GIL”,我不能 100% 确定那是什么你的意思是……
    • 我使用短语“低于 GIL”是因为提问者使用了它,但我可能应该更清楚一点,我并不是说 VM 允许其他线程工作当有一个与 C 接口的阻塞调用时。
    【解决方案2】:

    您提到的所有功能都不会自动并行化。一般来说,在大多数语言中,静默生成线程被认为是糟糕的形式(这种情况正在发生变化,但它仍然只在纯函数式语言中看到,其中线程安全是通过设计来实现的);在不发出警告的情况下产生大量线程是当用户尝试在其中启动自己的线程并由于运行线程过多而导致暂时错误时出现神秘错误的方式。因此,即使 GIL 不是问题,这样做也没有任何意义。

    也就是说,GIL 是用来保护解释器内部的,它涵盖了任何不断地操纵引用计数的场景;除了极少数例外,在持有 GIL 的情况下,不可能对 PyObject*s(这是所有 Python 级别类型在 C 中表示的)做任何有意义的工作。通常,Python 内置只为阻塞操作(I/O、等待锁等)释放 GIL;仅在 GIL 发布正常的第三方 C 扩展(和ctypes)中,因为在这些情况下,他们将PyObjects 完全转换为 C 级别类型,在没有引用计数或其他内部结构的情况下释放 GIL接触,做昂贵的工作,重新获取 GIL,并将结果从 C 级类型转换回 Python 级对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      • 2011-07-07
      • 2014-09-25
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多