为什么GIL替代品会对性能产生影响?

时间:2013-08-21 23:33:38

标签: python ruby multithreading performance gil

来自Java,Ruby和Python中的整个全局解释器锁(GIL)有点令人吃惊。我已经阅读了一些问题,并在Python documentation以下摘录中找到了:

  

我们不能摆脱Global Interpreter Lock吗?

     
    

全球化     解释器锁(GIL)通常被视为Python的障碍     在高端多处理器服务器机器上部署,因为a     多线程Python程序实际上只使用一个CPU,因为     坚持认为(几乎)所有Python代码只能在运行时运行     GIL举行。

         

回到Python 1.5的时代,Greg Stein实际上实现了一个     删除的综合补丁集(“免费线程”补丁)     GIL并用细粒度锁定代替它。不幸的是,甚至     在Windows上(锁非常有效)这就是普通的Python     代码大约是使用GIL的解释器的两倍慢。在Linux上     性能损失甚至更糟,因为pthread锁不是     高效。

  

我没有找到的是性能影响背后的解释。我试图找出技术原因是什么,但找不到任何有关它的好讨论。

类似于Ruby,在这里我可以找到更少的信息。原因是一样的吗?

2 个答案:

答案 0 :(得分:3)

简单地说,锁定和解锁许多锁比锁定和解锁单个锁更昂贵。这不应该是令人惊讶的,做任何事情 N次而不是一次明显需要更多时间(所有其他事情都是平等的)。对于这种事情,规模经济学并不真正适用,对所有锁定操作摊还没有大的一次性成本。

编辑:原则上,Java存在同样的问题,但是由于所涉及的每个人,历史以及可能的其他因素的焦点不同,Java可以很好地处理细粒度的锁。简而言之,单线程性能不被视为 重要,并且多线程性能可能比假设的自由线程CPython更好。

从历史上看,我认为没有一个带有GIL的JVM(虽然它最初是在单个操作系统线程上运行的绿色线程 - 但这很久以前),所以没有历史原因来保持GIL和没有基线单线程性能让人厌恶锁定。相反,我们付出了很多努力使Java擅长多线程,并且这种能力被广泛使用。相比之下,即使您解决了GIL问题而没有单线程Python或Ruby程序的性能成本,大多数代码都不会从中受益而且库也不是很糟糕,但并不完全与{ {1}}。

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

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

答案 1 :(得分:1)

大多数Python程序都是单线程的。那些没有的人往往走向多重处理的方向。

对于那些不适合多处理的人来说,可以使用C扩展来释放GIL,但当然你必须非常小心。

每次删除GIL的尝试都会对所有这些单线程/多处理应用程序的性能产生严重影响,因此GIL会保留,每个人都会尝试利用多处理,在大多数情况下,这是最好的解决方案。