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

2024-04-20 07:05:43 发布

您现在位置:Python中文网/ 问答频道 /正文

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

Can’t we get rid of the Global Interpreter Lock?

The global interpreter lock (GIL) is often seen as a hindrance to Python’s deployment on high-end multiprocessor server machines, because a multi-threaded Python program effectively only uses one CPU, due to the insistence that (almost) all Python code can only run while the GIL is held.

Back in the days of Python 1.5, Greg Stein actually implemented a comprehensive patch set (the “free threading” patches) that removed the GIL and replaced it with fine-grained locking. Unfortunately, even on Windows (where locks are very efficient) this ran ordinary Python code about twice as slow as the interpreter using the GIL. On Linux the performance loss was even worse because pthread locks aren’t as efficient.

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

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


Tags: ofthetoonlythatisonas
2条回答

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

编辑:原则上,Java也有同样的问题,但是由于每个人的关注点不同,历史,也许还有其他因素,Java在细粒度锁方面表现得相当不错。简言之,单线程性能并不被认为是重要的,多线程性能可能比假设的自由线程CPython要好。在

从历史上看,我不认为JVM有GIL(虽然它一开始是在单个OS线程上运行的绿色线程,但这是很久以前的事了),所以没有历史原因保留GIL,也没有基线单线程性能让人们厌恶锁。相反,我们花了很多精力让Java擅长多线程,这种能力得到了广泛的应用。相比之下,即使您解决了GIL问题,而没有为单线程Python或Ruby程序带来性能成本,大多数代码也不会从中受益,而且库是。。。不可怕,但也不完全与java.util.concurrent相提并论。在

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

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

大多数Python程序都是单线程的。那些不常用的方法通常都是朝着多处理的方向发展。在

对于那些不适合多处理的,可以使用C扩展来发布GIL,但是你必须非常小心。在

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

相关问题 更多 >