Después de mucho debate, el Comité Directivo del Lenguaje Python tiene la intención de aprobar una propuesta, PEP 703"Hacer que el bloqueo global del intérprete sea opcional en CPython". Esta propuesta es la culminación de muchos intentos a lo largo de los años para eliminar el bloqueo global del Global Interpter Lock (GIL) de Python. Su eliminación elimina una barrera importante para los subprocesos múltiples, lo que mejora significativamente su rendimiento para cargas de trabajo en paralelo. Con esta propuesta, el soporte de primera clase para subprocesos múltiples y concurrencia en Python está un paso más cerca de convertirse en realidad.
Un cuello de botella llamado GIL
El sistema de gestión de memoria de Python rastrea el uso de objetos contando el número de referencias a cada objeto. Cuando el recuento de referencias de un objeto cae a cero, el objeto está destinado a ser eliminado. Debido a que Python se creó en una época en la que los sistemas multiprocesador eran raros y los procesadores multinúcleo no existían, este mecanismo de recuento de referencias no es seguro para subprocesos. En cambio, Python proporciona seguridad para subprocesos al permitir que solo un subproceso acceda a un objeto a la vez. Para eso existe GIL.
A lo largo de los años, muchos proyectos han intentado eliminar GIL. Permitieron que los programas multiproceso se ejecutaran más rápido, pero a costa de degradar el rendimiento de los programas de un solo subproceso. Dado que la gran mayoría de las aplicaciones Python son de una sola tarea, este fue un mal compromiso. Aunque las mejoras en GIL han mejorado su manejo de aplicaciones multiproceso, sigue siendo un cuello de botella importante. Los desarrolladores de Python finalmente decidieron eliminar GIL de CPython, pero sólo si se podía hacer sin ralentizar los programas de una sola tarea.
¿Cómo funcionará Python sin GIL?
Las propuestas actuales para una edición de Python sin GIL utilizan una combinación de técnicas para hacer que el recuento de referencias sea seguro para los subprocesos y no modifican la velocidad de los programas de un solo subproceso o tienen un impacto mínimo. Primero está el recuento de referencias sesgado. El recuento de objetos a los que accede un único subproceso se maneja de forma diferente (y más rápido) que el recuento de objetos a los que acceden varios subprocesos. Dado que a la mayoría de los objetos solo se accede mediante un único subproceso, se minimiza el impacto en los programas de un solo subproceso. La inmortalización, por otro lado, se basa en el hecho de que algunos objetos, como Ninguno, nunca necesitan ser desasignados, por lo que no es necesario realizar un seguimiento de sus recuentos de referencias.
Otra técnica, la asignación de memoria a prueba de subprocesos, es un nuevo sistema de asignación de memoria para objetos CPython que facilitará el seguimiento de objetos en el llamado recolector de basura y asignará memoria de manera segura para subprocesos. Finalmente, otra técnica, llamada recuento de referencias diferidas, propone que el recuento de referencias de ciertos objetos, como las funciones de alto nivel de un módulo, se difiera de forma segura. Esto ahorra tiempo y recursos.
Adopción durante varios años.
La implementación del PEP 703 es un proyecto a largo plazo que se llevará a cabo en varias etapas durante varios años. Durante este período, el intérprete de CPython evolucionará para que la versión sin GIL sea primero opcional, luego compatible y finalmente la versión estándar de CPython. Para hacer esto, los desarrolladores de CPython agregarán un modo de compilación experimental "no-GIL" a CPython, de modo que se pueda compilar una versión de CPython con o sin GIL. Con el tiempo, el modo de compilación "no-GIL" se convertirá en el predeterminado. Así va el proyecto de eliminación de GIL en CPython. Las primeras encarnaciones de CPython sin GIL serán experimentales, tanto para los desarrolladores de CPython como para la comunidad de Python en general. Esta fase tiene varios objetivos. Primero, involucre al resto de la comunidad Python. Cualquier cambio importante en Python requiere la participación de toda la comunidad Python. Las compilaciones experimentales permiten a los usuarios de Python probar su código de forma segura y ver cómo se comportará el código con y sin subprocesos.
También se trata de dar a las distribuciones de Python la posibilidad, y no la obligación, de entregar Python sin GIL. Las distribuciones de Python como Conda o WinPython deben garantizar la compatibilidad con CPython. Durante la fase de transición, podrían ofrecer la posibilidad de instalar la versión normal o libre de GIL de CPython. Esto permitiría a los usuarios de Conda o WinPython elegir la versión más compatible con sus necesidades. Finalmente, durante esta fase experimental, se trata de determinar si el proyecto sin GIL vale la pena. Si la comunidad prueba las versiones libres de GIL a gran escala y no está satisfecha con los resultados, los desarrolladores de CPython se reservan el derecho de retroceder. Tener dos versiones significa una mayor carga de mantenimiento a corto plazo, pero proporciona una salida si el proyecto sin GIL resulta indigno.
Establezca una fecha límite para que no-GIL sea la versión predeterminada
El segundo paso será ofrecer la versión sin GIL como versión alternativa compatible para CPython. Un usuario tendrá la opción de instalar la versión sin GIL o la versión GIL, cualquiera de las cuales es una versión oficialmente compatible de CPython que recibe correcciones de errores, parches de seguridad y actualizaciones. Uno de los principales objetivos de este paso es establecer una fecha límite para que no-GIL sea la opción predeterminada. Es probable que esto suceda en el mismo cronograma que la desaprobación y eliminación de otras características de Python: al menos dos o tres lanzamientos, lo que significa al menos dos o tres años.
El último paso sería hacer que la versión sin GIL de CPython sea la predeterminada y eliminar todo el código relacionado con GIL de CPython. "No queremos esperar demasiado" escribe Thomas Wouters, desarrollador líder de CPython“Porque tener dos modos de compilación comunes puede ser una gran carga para la comunidad (porque, por ejemplo, puede duplicar los recursos de prueba y los escenarios de depuración), pero tampoco podemos apresurarnos. Creemos que se necesitarán hasta cinco años para llegar a este punto”.
Los mayores desafíos de eliminar GIL
Los mayores desafíos de este plan no son sólo técnicos, aunque sí considerables. Lo que es aún más importante es saber cómo alinear el resto del ecosistema Python con estos cambios y garantizar que un Python sin GIL no cree más problemas de los que resuelve. Según Thomas Wouters, "cualquier cambio en el código de terceros necesario para acomodar versiones sin GIL debería funcionar en versiones con GIL (aunque aún se debe considerar la compatibilidad con versiones anteriores de Python)".
El otro gran desafío, como se mencionó anteriormente, es "atraer al resto de la comunidad Python", continúa, "...y asegurarnos de que los cambios que queremos hacer y los cambios que queremos que ellos hagan, son aceptables. Antes de comprometernos a pasar completamente a la versión libre de GIL, necesitamos obtener el apoyo de la comunidad", agrega este desarrollador. "No podemos simplemente cambiar la configuración predeterminada y esperar que la comunidad entienda el trabajo que tienen que hacer. hacer para apoyarlo”. La comunidad Python experimentó enormes dificultades durante la transición de Python 2 a Python 3, por lo que cualquier cambio significativo, como eliminar el GIL, debería ser perfectamente compatible con versiones anteriores. Como dice Thomas Wouters, "no queremos otra situación con Python 3".
Otras noticias que te pueden interesar