¿Por qué no hay GIL en la Máquina Virtual de Java? ¿Por qué Python necesita uno tan mal?

Espero que alguien pueda darnos una idea de lo que es fundamentalmente diferente acerca de la Máquina Virtual de Java que le permite implementar subprocesos muy bien sin la necesidad de un Bloqueo de Intérprete Global (GIL), mientras que Python necesita tal maldad.

Python (el lenguaje) no necesita un GIL (por lo que puede implementarse perfectamente en JVM [Jython] y .NET [IronPython], y esas implementaciones se pueden multihilo libremente). CPython (la implementación popular) siempre ha utilizado una GIL para facilitar la encoding (especialmente la encoding de los mecanismos de recolección de basura) y la integración de bibliotecas con código C no seguras para subprocesos (solía haber una tonelada de personas; -).

El proyecto Unladen Swallow , entre otros objectives 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 multihilo en Python. Creemos que esto es posible a través de la implementación de un sistema GC más sofisticado, algo así como el Recycler de IBM (Bacon et al, 2001) “.

La JVM (al menos punto de acceso) tiene un concepto similar al “GIL”, es mucho más fina en su granularidad de locking, la mayor parte de esto proviene de los GC en el punto de acceso que son más avanzados.

En CPython es un gran locking (probablemente no sea tan cierto, pero lo suficientemente bueno como para tener argumentos), 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 de seguridad, la VM completa se ha detenido con respecto al código Java, al igual que la VM de python se detiene en la GIL.

En el mundo Java, tales eventos de pausa de VM se conocen como “stop-the-world”, en estos puntos solo el código nativo que está vinculado a ciertos criterios se ejecuta libremente, el rest de la VM se ha detenido.

Además, la falta de un locking 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 las llamadas FFI, una de las cosas que cpython hace bastante fácil (aunque no tan fácil como usar ctypes).

Hay un comentario más abajo en esta publicación del blog http://www.grouplens.org/node/244 que sugiere la razón por la cual 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.

En este enlace tienen la siguiente explicación:

… “Las partes del intérprete no son seguras para subprocesos, aunque principalmente porque hacerlas todas seguras para subprocesos mediante el uso masivo de lockings sería extremadamente lenta ( fuente ). Esto parece estar relacionado con el recolector de basura CPython mediante el recuento de referencias y CLR no lo hace, y por lo tanto no es necesario 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 “.

Python carece de jit / aot y el período de tiempo que se escribió en procesadores multiproceso no existía. Alternativamente, puedes volver a comstackr todo en Julia lang, que carece de GIL, y ganar algo de velocidad en tu código Python. También Jython es un poco más apestoso que es más lento que Cpython y Java. Si quieres mantenerte en Python, considera usar complementos paralelos, no obtendrás un aumento de velocidad instantáneo, pero puedes hacer una progtwigción paralela con el complemento correcto.