Python 为什么GIL替代方案会对绩效产生影响?

Python 为什么GIL替代方案会对绩效产生影响?,python,ruby,multithreading,performance,gil,Python,Ruby,Multithreading,Performance,Gil,来自Java的Ruby和Python中的全局解释器锁(GIL)有点令人吃惊。我读了一些关于这个问题的文章,在下面的摘录中发现: 我们不能摆脱全局解释器锁吗? 全球 解释器锁(GIL)通常被视为Python的一个障碍 在高端多处理器服务器计算机上部署,因为 多线程Python程序实际上只使用一个CPU,因为 坚持认为(几乎)所有Python代码只能在 吉尔被拘留了 回到Python1.5时代,Greg Stein实际上实现了 已删除的全面修补程序集(“自由线程”修补程序) GIL并将其替换为细粒度

来自Java的Ruby和Python中的全局解释器锁(GIL)有点令人吃惊。我读了一些关于这个问题的文章,在下面的摘录中发现:

我们不能摆脱全局解释器锁吗?

全球 解释器锁(GIL)通常被视为Python的一个障碍 在高端多处理器服务器计算机上部署,因为 多线程Python程序实际上只使用一个CPU,因为 坚持认为(几乎)所有Python代码只能在 吉尔被拘留了

回到Python1.5时代,Greg Stein实际上实现了 已删除的全面修补程序集(“自由线程”修补程序) GIL并将其替换为细粒度锁定。不幸的是,甚至 在Windows上(锁非常有效)运行普通Python 使用GIL编写代码的速度大约是解释器的两倍。在Linux上 性能损失甚至更严重,因为pthread锁没有达到预期的效果 效率高

我没有找到性能影响背后的解释。我试图找出技术上的原因是什么,但找不到任何好的讨论来解决这个问题


与Ruby类似,在这里我可以找到更少的信息。原因是否相同?

简单地说,锁定和解锁多个锁比锁定和解锁单个锁更昂贵。这并不奇怪,做任何事情N次而不是一次明显的事情都需要更多的时间(所有其他事情都是一样的)。对于这类事情,规模经济并不真正适用,在所有锁定操作中没有大的一次性成本可以摊销

编辑:原则上,Java也有同样的问题,但由于涉及的每个人的关注点、历史以及可能的其他因素的不同,Java可以很好地使用细粒度锁。简言之,单线程性能并不重要,多线程性能可能比假设的自由线程CPython更好

从历史上看,我认为从来没有一个JVM有GIL(虽然它最初是在一个操作系统线程上运行绿色线程——但这是很久以前的事了),所以没有历史原因来保持GIL,也没有让人们讨厌锁的基线单线程性能。取而代之的是,在使Java擅长多线程方面投入了大量精力,并且这种能力得到了广泛的应用。相比之下,即使您解决了单线程Python或Ruby程序的GIL问题,并且没有任何性能成本,大多数代码也不会从中受益,而且库是。。。不可怕,但与java .UTI.Outux<代码>也不完全相同。

因为Java(现在)有一个内存模型,它显式地不提供很多保证,所以Java程序中的许多常见操作通常不需要任何类型的锁。当然,缺点是Java程序员必须在需要时手动添加锁或其他同步。 此外,Java的锁已经对锁进行了很多优化(其中一些是最初的研究,并首次在JVM中引入),如精简锁、锁省略等,这使得具有争用的锁非常便宜


另一个因素可能是Java程序几乎完全运行Java代码(如上所述,如果没有显式请求,则只需要很少的同步),只需要对运行库进行很少的调用。因此,一个自由线程的JVM甚至可以为JIT、类加载器等提供全局锁(或者只有几个粗略的锁),而不会对大多数Java程序产生太大的影响。相比之下,Python程序将大部分时间花在C代码上,无论是内置模块还是第三方扩展模块。

简单地说,锁定和解锁多个锁比锁定和解锁单个锁更昂贵。这并不奇怪,做任何事情N次而不是一次明显的事情都需要更多的时间(所有其他事情都是一样的)。对于这类事情,规模经济并不真正适用,在所有锁定操作中没有大的一次性成本可以摊销

编辑:原则上,Java也有同样的问题,但由于涉及的每个人的关注点、历史以及可能的其他因素的不同,Java可以很好地使用细粒度锁。简言之,单线程性能并不重要,多线程性能可能比假设的自由线程CPython更好

从历史上看,我认为从来没有一个JVM有GIL(虽然它最初是在一个操作系统线程上运行绿色线程——但这是很久以前的事了),所以没有历史原因来保持GIL,也没有让人们讨厌锁的基线单线程性能。取而代之的是,在使Java擅长多线程方面投入了大量精力,并且这种能力得到了广泛的应用。相比之下,即使您解决了单线程Python或Ruby程序的GIL问题,并且没有任何性能成本,大多数代码也不会从中受益,而且库是。。。不可怕,但与java .UTI.Outux<代码>也不完全相同。

因为Java(现在)有一个内存模型,它显式地不提供很多保证,所以Java程序中的许多常见操作通常不需要任何类型的锁。当然,缺点是Java程序员必须在需要时手动添加锁或其他同步。 此外,Java的锁已经对锁进行了很多优化(其中一些是最初的研究,并首次在JVM中引入),如精简锁、锁省略等,这使得具有争用的锁非常便宜

另一个因素可能是Java程序几乎完全运行Java代码(如上所述,如果没有显式请求,则只需要很少的同步),只需对运行库进行很少的调用