Pourquoi n'y a-t-il pas de GIL dans la machine virtuelle Java? Pourquoi Python en a-t-il tellement besoin?

177

J'espère que quelqu'un pourra donner un aperçu de ce qui est fondamentalement différent de la machine virtuelle Java qui lui permet d'implémenter correctement les threads sans avoir besoin d'un Global Interpreter Lock (GIL), alors que Python nécessite un tel mal.

AgentLiquide
la source

Réponses:

223

Python (le langage) n'a pas besoin d'un GIL (c'est pourquoi il peut parfaitement être implémenté sur JVM [Jython] et .NET [IronPython], et ces implémentations multithread librement). CPython (l'implémentation populaire) a toujours utilisé un GIL pour faciliter le codage (en particulier le codage des mécanismes de ramasse-miettes) et l'intégration de bibliothèques codées en C non thread-safe (il y en avait une tonne autour; -).

Le projet Unladen Swallow , entre autres objectifs ambitieux, prévoit une machine virtuelle sans GIL pour Python - pour citer ce site, "De plus, nous avons l'intention de supprimer le GIL et de corriger l'état du multithreading en Python. Nous pensons que c'est possible grâce à la mise en œuvre d'un système GC plus sophistiqué, quelque chose comme IBM's Recycler (Bacon et al, 2001). "

Alex Martelli
la source
6
Alex, qu'en est-il des anciennes tentatives de suppression du GIL, n'y avait-il pas une tonne de frais généraux avec ça (un facteur de 2 est ce dont je me souviens)?
Bartosz Radaczyński
10
Oui Bartosz, Greg Stein a mesuré cela en 1999. Le ramassage des ordures par comptage de références était le tueur, forçant d'énormes frais généraux de verrouillage à grain fin. C'est pourquoi un GC plus avancé y est crucial.
Alex Martelli
80
L'équipe Unladen Swallow a renoncé à supprimer le GIL: code.google.com/p/unladen-swallow/wiki/…
Seun Osewa
1
Les alternatives à Unladen et CPython sont PyPy, Jython et IronPython. Les deux derniers n'ont pas de GIL, mais l'utilisation du module multitraitement évite le GIL et est de toute façon plus sûr.
Cees Timmerman
50

Le JVM (au moins hotspot) a un concept similaire au "GIL", il est juste beaucoup plus fin dans sa granularité de verrouillage, la plupart de cela vient des GC in hotspot qui sont plus avancés.

Dans CPython, c'est un gros verrou (probablement pas si vrai, mais assez bon pour les arguments), dans la JVM, il est plus répandu avec différents concepts en fonction de l'endroit où il est utilisé.

Jetez un œil, par exemple, à vm / runtime / safepoint.hpp dans le code du hotspot, qui est en fait une barrière. Une fois à un point de restauration, la machine virtuelle entière s'est arrêtée en ce qui concerne le code java, tout comme la machine virtuelle python s'arrête au GIL.

Dans le monde Java, ces événements de pause de VM sont connus sous le nom de "stop-the-world", à ces moments, seul le code natif lié à certains critères fonctionne librement, le reste de la VM a été arrêté.

De plus, l'absence de verrouillage grossier en java rend JNI beaucoup plus difficile à écrire, car la JVM offre moins de garanties sur son environnement pour les appels FFI, une des choses que cpython rend assez facile (bien que pas aussi facile que l'utilisation de ctypes).

Greg Bowyer
la source
7

Il y a un commentaire ci-dessous dans ce billet de blog http://www.grouplens.org/node/244 qui fait allusion à la raison pour laquelle il était si facile de se passer d'un GIL pour IronPython ou Jython, c'est que CPython utilise le comptage de références alors que les 2 autres VM ont des garbage collector.

La mécanique exacte de la raison pour laquelle c'est si je ne comprends pas, mais cela semble être une raison plausible.

user235859
la source
5
Lorsque vous partagez des objets de manière promiscue entre les threads, travailler lorsque personne n'a plus de référence à un objet particulier est modérément gênant. Le comptage de références avec un verrou global est un moyen (coûteux). Une manière différente de le résoudre aurait été de ne laisser qu'un seul thread à la fois contenir des références à l'objet, ce qui rendrait la plupart des activités locales au thread au prix de rendre les communications inter-thread plus gênantes. Personnellement, je pense que c'est révélateur que HPC utilise le passage de messages entre processeurs et non la mémoire partagée, et qu'il le fait pour des raisons d'évolutivité ...
Donal Fellows
0

Dans ce lien ils ont l'explication suivante:

... "Certaines parties de l'interpréteur ne sont pas sécurisées pour les threads, mais principalement parce que les rendre toutes sécurisées par un verrouillage massif ralentirait extrêmement les threads uniques ( source ). Cela semble être lié au ramasse-miettes CPython utilisant le comptage de références (la JVM et CLR ne le font pas, et n'ont donc pas besoin de verrouiller / libérer un décompte de références à chaque fois). Mais même si quelqu'un pensait à une solution acceptable et la mettait en œuvre, les bibliothèques tierces auraient toujours les mêmes problèmes. "

Oliver Wilken
la source
-1

Python manque de jit / aot et le délai dans lequel il a été écrit sur des processeurs multithreads n'existait pas. Alternativement, vous pouvez recompiler tout dans Julia lang qui manque de GIL et gagner en vitesse sur votre code Python. De plus, Jython craint qu'il soit plus lent que Cpython et Java. Si vous souhaitez vous en tenir à Python, envisagez d'utiliser des plugins parallèles, vous ne bénéficierez pas d'un gain de vitesse instantané, mais vous pouvez faire de la programmation parallèle avec le bon plugin.

Jim
la source
qu'en est-il de PyPy?
denis631