[PyVigo] Erlang: The Road to the JIT
José Juan Montes
jjmontes en gmail.com
Vie Dic 18 21:20:44 CET 2020
Oh, cómo lamento habérmelo perdido.
Jose Juan Montes
El vie, 18 dic 2020 a las 18:57, Jesus Cea (<jcea en jcea.es>) escribió:
> Ya sé que esto es Erlang, pero me parece un artículo interesante y
> relevante para la tertulia del martes pasado y la discusión de por qué
> CPYTHON no tiene JIT de serie.
>
> https://blog.erlang.org/the-road-to-the-jit/
>
> Tema "guardas" que comentaba en en la tertulia del martes. Las "guardas"
> con comprobaciones que confirman invariantes para ejecutar código
> optimizado. Por ejemplo, una invariante podría ser que un tipo concreto
> sigue siendo un entero porque antes lo fue.
>
> Ejemplo:
>
> Sea el código:
>
> """
> def suma(n):
> s = 0
> for i in range(n):
> s += i
> return s
> """
>
> Python 3.9 compila este código al siguiente bytecode:
>
> """
> >>> dis.dis(suma)
> 2 0 LOAD_CONST 1 (0)
> 2 STORE_FAST 1 (s)
>
> 3 4 LOAD_GLOBAL 0 (range)
> 6 LOAD_FAST 0 (n)
> 8 CALL_FUNCTION 1
> 10 GET_ITER
> >> 12 FOR_ITER 12 (to 26)
> 14 STORE_FAST 2 (i)
>
> 4 16 LOAD_FAST 1 (s)
> 18 LOAD_FAST 2 (i)
> 20 INPLACE_ADD
> 22 STORE_FAST 1 (s)
> 24 JUMP_ABSOLUTE 12
>
> 5 >> 26 LOAD_FAST 1 (s)
> 28 RETURN_VALUE
> """
>
> Aquí se podrían optimizar cosas como reconocer "range", pero
> centrándonos en el cuerpo del bucle, se podría reconocer perfectamente
> que tanto "s" como "i" son enteros y operar con ellos directamente como
> tipos de datos en ensamblador.
>
> Estudiando el código generado, se puede ver que es muy mejorable. Por
> ejemplo, se podría mover la línea 16 a antes del bucle y eliminar las
> líneas 22 y 26, manteniendo "s" en el stack en vez de guardarlo en una
> variable para cargarlo inmediatamente después. De hecho se podría hasta
> eliminar la actualización de "s" en memoria hasta el final del bucle.
> También se podría prescindir de guardar el contador del bucle en la
> variable "i", eliminando las líneas 14 y 18. ¡El cuerpo del bucle
> pasaría de 5 instrucciones a una!. La única complejidad sería la gestión
> de excepciones: Si la suma levanta una excepción, habría que reconstruir
> las variables "i" y "s".
>
> La guarda se podría poner en el INPLACE_ADD, pero haciendo inferencia de
> tipos trivial se podría compilar a ensamblador todo el cuerpo del bucle,
> y la guarda sería simplemente comprobar que ni "i" ni "s" se pasan de
> 32/64 bits, que sería el tipo básico en ensamblador. Mientras ni "i" ni
> "s" se pasen de ese rango, se pueden manejar en registros de ensamblador
> y hacer una conversión a tipos Python al terminar el bucle. Si te pasas
> del rango, pues simplemente ejecutas el bytecode habitual, algo
> transparente para el programa.
>
> El intérprete de bytecode tiene el siguiente fragmento para ejecutar
> "INPLACE_ADD":
>
> """
> case TARGET(INPLACE_ADD): {
> PyObject *right = POP();
> PyObject *left = TOP();
> PyObject *sum;
> if (PyUnicode_CheckExact(left) &&
> PyUnicode_CheckExact(right)) {
> sum = unicode_concatenate(tstate, left, right, f,
> next_instr);
> /* unicode_concatenate consumed the ref to left */
> }
> else {
> sum = PyNumber_InPlaceAdd(left, right);
> Py_DECREF(left);
> }
> Py_DECREF(right);
> SET_TOP(sum);
> if (sum == NULL)
> goto error;
> DISPATCH();
> }
> """
>
> Se ve una optimización cuando los operandos son unicode, pero en el caso
> de números el código es más complejo.
>
> El problema fundamental de Python es que técnicamente podrías capturar
> el "traceback" de otro hilo y examinar sus tipos locales, pero una
> solución evidente sería retrasar esa captura hasta que se llega al final
> del cuerpo del bucle (no al final del bucle, si no del cuerpo del
> bucle). Otro problema es la gestión de excepciones, que habría que
> reconstruir el traceback y los valores de variables "optimizadas". Por
> lo que sé, los JIT actuales de Python como NUMBA simplemente obvian este
> problema, normalmente suponiendo que no hay excepciones.
>
> --
> Jesús Cea Avión _/_/ _/_/_/ _/_/_/
> jcea en jcea.es - https://www.jcea.es/ _/_/ _/_/ _/_/ _/_/ _/_/
> Twitter: @jcea _/_/ _/_/ _/_/_/_/_/
> jabber / xmpp:jcea en jabber.org _/_/ _/_/ _/_/ _/_/ _/_/
> "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/
> "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/
> "El amor es poner tu felicidad en la felicidad de otro" - Leibniz
>
> _______________________________________________
> Asociación Python España: https://www.es.python.org/
> Python Vigo: https://www.python-vigo.es/
> Vigo mailing list
> Vigo en lists.es.python.org
> https://lists.es.python.org/listinfo/vigo
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <https://lists.es.python.org/pipermail/vigo/attachments/20201218/37991d07/attachment.htm>
Más información sobre la lista de distribución Vigo