TOC

Python GIL 的最新动态

开源中国上看到有人通过一些实验验证来视图说服 Python 核心团队移除 GIL,根据他的数据,移除 GIL 在某些基准测试中大幅提升了多线程性能(19.8 倍)。

我在网上看到很多转载直接说移除 GIL 性能提升 19 倍,这肯定是夸大 + 歪曲事实。

之前是说,社区多次有人尝试移除 GIL,但是效果都不明显,反而给项目增加了很多复杂性。

我认为:1. GIL 的设计不好;2. 如果没有 GIL,设计精良的多线程程序对资源会有更好的利用。但我还是不认为这个消息中的 19.8 这个数字有那么大的意义,其测试用例应该只是一个极限情况,不具备现实意义。

如果 GIL 移除,那对于 Python 生态来说,破坏性要比 2to3 强 100 倍,可能很多重要的项目都需要作出调整。我期待的 GIL 移除会以一种拓展的形式出现,比如通过系统变量,命令参数,或者函数开关,或者新的线程库之类方式。千万不能让已有的代码无法正常运行。

一位名叫 Sam Gross 的开发者提出了一个对全局解释器锁(GIL)进行重大修改的设想。其目标在于移除 CPython 中的 GIL,以使得多线程能够并行执行 Python 代码。目前,该项目已经引起了 Python 核心开发团队的关注。

我一直在对 CPython 进行修改,使其能够在没有全局解释器锁的情况下运行。我想与大家分享一个可以在没有 GIL 的情况下运行的概念验证。这个概念验证涉及到对 CPython 内部的大量修改,但对 C-API 的修改相对较少。它可以与许多 C 语言扩展兼容:扩展必须被重建,但通常只需要对源代码进行较小的修改或不需要修改。我已经从科学的 Python 生态系统中构建了兼容的软件包版本,它们可以通过捆绑的"pip"来安装。

SamGross

Gross 在设计文档中详细列举了移除 GIL 需要承担的一些风险以及他认为要移除 GIL 的理由:

风险

  • 移除 GIL 将是一项大型、多年的任务,引入错误和回归的风险会增加。
  • 移除 GIL 意味着在单线程和多线程性能之间进行权衡。“我相信 - 我们可以创建一个没有 GIL 的 CPython,它在单线程和多线程工作负载方面都比当前的 CPython 更快;但是如果我们保留 GIL 并只专注于单线程工作负载,我们将实现更好的单线程性能”。(有关更多详细信息,可参阅“Performance”部分。)
  • 大多数 Python 程序都没有针对多线程性能进行优化;他们可能需要更改以利用没有 GIL 的运行。
  • 多线程程序容易出现并发错误。尽管 Python 已经支持线程(with the GIL),但成功移除 GIL 可能会增加线程的使用,从而导致 Python 程序员暴露于并发错误。

为什么要移除 GIL?

  • GIL 是并发的主要障碍。对于科学计算任务,这种缺乏并发性通常比执行 Python 代码的速度更重要,因为大部分处理器周期都花费在优化的 CPU 或 GPU 内核中。GIL 引入了一个全局瓶颈,如果其他线程调用任何 Python 代码,它都会阻止其他线程取得进展。
  • 在“Why Swift for Tensorflow”文档中,Chris Lattner 写道“GIL 在大规模设置中增加了整个堆栈的复杂性:它使模型作者无法为某些事情实现合理的性能(无需自己编写 C++/CUDA),并阻止模型中的并发算法的自然表达。”
  • 围绕 GIL 进行了大量工程工作。这样做的后果之一是,简单地删除 GIL 不太可能神奇地提高现有代码的速度。但是 Gross 认为,移除 GIL 将可以更容易的利用并行性、简化新库的开发、并允许改进现有库。

Gross 称,自己进行概念验证的目的是想要证明,取消 GIL 是可行的和值得的;且这个项目的技术想法可以作为这种努力的基础。同时,他也想就这些想法和大家展开讨论,并衡量社区对这种移除 GIL 的方法的兴趣。

如果 Gross 的提议被接受,就会重写 Python 在其运行时从多个线程访问对象的序列化方式,并将显着提高多线程的性能。这个项目对 Python 字节码解释器(ceval.c)进行了大幅修改;目的在于提高单线程性能,减少引用计数变化对性能的影响,以及提高多线程运行时的可扩展性。

测试结果表明,无 GIL 概念验证的解释器在单线程的 pyperformance 基准上比 CPython 3.9(和 3.10)快 10% 左右。截至 2021 年 9 月初,它的平均性能与 CPython 3.11 的"main"分支大致相同。在一些基准测试中,多线程性能实现了良好的提升。例如,在有 20 个线程的情况下,有一个基准测试中的任务速度提高了 18.1 倍,另一个基准测试中的任务速度则提高了 19.8 倍。

InfoWorld 认为,Gross 的提议包含了很大的更改,以至于相当数量的直接与 Python 内部运作的现有 Python 库(例如 Cython))都需要进行重写。但是,Python 的发布时间表的节奏则意味着,这种破坏性变更需要在一个主要版本而不是次要版本中进行发布。

参考资料与拓展阅读