¿Por qué no hay GIL en la máquina virtual Java? ¿Por qué Python necesita uno tan malo?

177

Espero que alguien pueda proporcionar una idea de lo que es fundamentalmente diferente acerca de la Máquina virtual Java que le permite implementar hilos sin la necesidad de un Bloqueo de intérprete global (GIL), mientras que Python necesita tal maldad.

Agente Líquido
fuente

Respuestas:

223

Python (el lenguaje) no necesita un GIL (por lo que se puede implementar perfectamente en JVM [Jython] y .NET [IronPython], y esas implementaciones se multiproponen libremente). CPython (la implementación popular) siempre ha usado un GIL para facilitar la codificación (especialmente la codificación de los mecanismos de recolección de basura) y para la integración de bibliotecas codificadas en C que no son seguras para subprocesos (solía haber un montón de ellas; -).

El proyecto Unladen Swallow , entre otros objetivos ambiciosos, planifica una máquina virtual sin GIL para Python, para citar ese sitio: "Además, tenemos la intención de eliminar el GIL y corregir el estado de subprocesamiento múltiple en Python. Creemos que esto es posible a través de la implementación de un sistema GC más sofisticado, algo como el Recycler de IBM (Bacon et al, 2001) ".

Alex Martelli
fuente
66
Alex, ¿qué pasa con los viejos intentos de eliminar el GIL? ¿No hubo un montón de gastos generales con eso (un factor de 2 es lo que recuerdo)?
Bartosz Radaczyński el
10
Sí Bartosz, Greg Stein midió eso en 1999. La recolección de basura por recuento de referencias fue la causa de muerte, forzando una gran sobrecarga de bloqueo de grano fino. Es por eso que un GC más avanzado es crucial allí.
Alex Martelli el
80
El equipo de Unladen Swallow ha renunciado a eliminar el GIL: code.google.com/p/unladen-swallow/wiki/…
Seun Osewa
1
Las alternativas a Unladen y CPython son PyPy, Jython y IronPython. Los dos últimos no tienen un GIL, pero el uso del módulo de multiprocesamiento elude al GIL y de todos modos es más seguro.
Cees Timmerman
50

El JVM (al menos hotspot) tiene un concepto similar al "GIL", es mucho más fino en su granularidad de bloqueo, la mayor parte proviene de los GC en el hotspot, que son más avanzados.

En CPython es un gran candado (probablemente no es tan cierto, pero es lo suficientemente bueno como argumento), en la JVM está más extendido con diferentes conceptos dependiendo de dónde se use.

Eche un vistazo a, por ejemplo, vm / runtime / safepoint.hpp en el código de punto de acceso, que es efectivamente una barrera. Una vez en un punto seguro, toda la VM se ha detenido con respecto al código de Java, al igual que la VM de Python se detiene en el GIL.

En el mundo de Java, tales eventos de pausa de VM se conocen como "detener el mundo", en estos puntos solo el código nativo que está vinculado a ciertos criterios se ejecuta libremente, el resto de la VM se ha detenido.

Además, la falta de un bloqueo grueso en Java hace que JNI sea mucho más difícil de escribir, ya que JVM ofrece menos garantías sobre su entorno para llamadas FFI, una de las cosas que cpython hace bastante fácil (aunque no tan fácil como usar ctypes).

Greg Bowyer
fuente
7

Hay un comentario a continuación en esta publicación de blog http://www.grouplens.org/node/244 que insinúa la razón por la que fue tan fácil prescindir de un GIL para IronPython o Jython, es que CPython usa el conteo de referencias mientras que Las otras 2 máquinas virtuales tienen recolectores de basura.

La mecánica exacta de por qué esto es así no lo entiendo, pero parece una razón plausible.

usuario235859
fuente
55
Cuando comparte objetos de manera promiscua entre subprocesos, hacer ejercicio cuando ya nadie tiene una referencia a un objeto en particular es moderadamente incómodo. El recuento de referencias con un bloqueo global es una forma (costosa). Una forma diferente de resolverlo habría sido dejar que solo un subproceso a la vez contenga referencias al objeto, lo que haría que la mayor parte de la actividad sea local en el subproceso a un costo de hacer que las comunicaciones entre subprocesos sean más incómodas. Personalmente, creo que es revelador que HPC utiliza el paso de mensajes entre procesadores y memoria no compartida, y que lo hace por razones de escalabilidad ...
Donal Fellows
0

En este enlace tienen la siguiente explicación:

... "Las partes del intérprete no son seguras para subprocesos, aunque sobre todo porque hacerlas todas seguras mediante el uso masivo de bloqueo ralentizaría extremadamente un solo subproceso ( fuente ). Esto parece estar relacionado con el recolector de basura CPython usando el conteo de referencias (la JVM y CLR no lo hacen, y por lo tanto no necesitan bloquear / liberar un recuento de referencias cada vez). Pero incluso si alguien pensara en una solución aceptable y la implementara, las bibliotecas de terceros seguirían teniendo los mismos problemas ".

Oliver Wilken
fuente
-1

Python carece de jit / aot y el marco de tiempo en que fue escrito en procesadores multiproceso no existía. Alternativamente, podría volver a compilar todo en Julia Lang que carece de GIL y obtener un aumento de velocidad en su código de Python. Además, Jython es una mierda, es más lento que Cpython y Java. Si desea apegarse a Python, considere usar complementos paralelos, no obtendrá un aumento instantáneo de la velocidad, pero puede hacer la programación paralela con el complemento correcto.

Jim
fuente
¿Qué hay de PyPy?
denis631