Cinder de codi obert de Facebook, una bifurcació de CPython utilitzada per Instagram

Facebook ha publicat el codi font del Projecte Cinder, una bifurcació de CPython 3.8.5, la principal implementació de referència del llenguatge de programació Python. Cinder s'utilitza a la infraestructura de producció de Facebook per alimentar Instagram i inclou optimitzacions per millorar el rendiment.

El codi es publica per discutir la possibilitat de portar les optimitzacions preparades al marc principal de CPython i per ajudar altres projectes implicats en la millora del rendiment de CPython. Facebook no té la intenció de donar suport a Cinder en forma de projecte de codi obert independent i el codi es presenta en la forma en què s'utilitza a la infraestructura de l'empresa, sense pentinat i documentació addicionals. Tampoc intenten promocionar Cinder com una alternativa a CPython: l'objectiu principal del desenvolupament és el desig de millorar el mateix CPython.

El codi Cinder es nota com a bastant fiable i provat en entorns de producció, però si s'identifiquen problemes, haureu de resoldre'ls vosaltres mateixos, ja que Facebook no garanteix que respondrà als missatges d'error externs i a les sol·licituds d'extracció. Al mateix temps, Facebook no exclou la cooperació constructiva amb la comunitat i està disposat a discutir idees sobre com fer que Cinder sigui encara més ràpid o com accelerar la transferència dels canvis preparats a la part principal de CPython.

Principals optimitzacions implementades a Cinder:

  • Emmagatzematge a la memòria cau en línia del bytecode ("shadow bytecode"). L'essència del mètode és identificar situacions en què s'executa un codi operatiu típic que es pot optimitzar i substituir dinàmicament aquest codi operatiu per opcions especialitzades més ràpides (per exemple, substituint funcions anomenades freqüentment).
  • Avaluació corrutina amb ganes. Per a les trucades de funcions asíncrones que es processen immediatament (wait no dóna lloc a una espera i la funció arriba a la instrucció de retorn abans), el resultat d'aquestes funcions es substitueix directament sense crear una corrutina ni implicar un bucle d'esdeveniments. En el codi de Facebook que utilitza en gran mesura async/wait, l'optimització es tradueix en una acceleració d'aproximadament un 5%.
  • Recopilació JIT selectiva a nivell de mètodes i funcions individuals (method-at-a-time). Habilitat mitjançant l'opció "-X jit" o la variable d'entorn PYTHONJIT=1 i us permet accelerar l'execució de moltes proves de rendiment entre 1.5 i 4 vegades. Com que la compilació JIT només és rellevant per a funcions executades amb freqüència, no és recomanable utilitzar-la per a funcions que s'utilitzen poc, la sobrecàrrega de compilació de les quals només pot alentir l'execució del programa.

    Mitjançant l'opció "-X jit-list-file=/path/to/jitlist.txt" o la variable d'entorn "PYTHONJITLISTFILE=/path/to/jitlist.txt" podeu especificar un fitxer amb una llista de funcions per a les quals JIT es pot utilitzar (format de ruta .to.module:nom_funció o ruta.to.module:ClassName.nom_mètode). La llista de funcions per a les quals s'hauria d'habilitar JIT es pot determinar en funció dels resultats del perfil. En el futur, s'espera suport per a la compilació JIT dinàmica basant-se en l'anàlisi interna de la freqüència de les trucades de funció, però tenint en compte les especificitats dels processos de llançament a Instagram, la compilació JIT també és adequada per a Facebook en l'etapa inicial.

    JIT primer converteix el codi de bytes de Python en una representació intermèdia d'alt nivell (HIR), que és força propera al codi de bytes de Python, però està dissenyat per utilitzar una màquina virtual basada en registres en comptes d'una de pila, i també utilitza informació de tipus i informació addicional. detalls crítics per al rendiment (com ara el recompte de referències). A continuació, el HIR es converteix en un formulari SSA (assignació única estàtica) i passa per passos d'optimització que tenen en compte els resultats del recompte de referència i les dades de consum de memòria. Com a resultat, es genera una representació intermèdia de baix nivell (LIR) propera al llenguatge ensamblador. Després d'una altra fase d'optimitzacions basades en LIR, es generen instruccions de muntatge mitjançant la biblioteca asmjit.

  • Mode estricte per als mòduls. La funcionalitat inclou tres components: Tipus StrictModule. Un analitzador estàtic que pot determinar que l'execució d'un mòdul no té cap impacte en el codi fora d'aquest mòdul. Un carregador de mòduls que determina que els mòduls estan en mode estricte (el codi especifica "import __strict__"), comprova l'absència d'interseccions amb altres mòduls i carrega mòduls estrictes a sys.modules com a objecte StrictModule.
  • Static Python és un compilador de bytecode experimental que utilitza anotacions de tipus per generar bytecode específic del tipus que s'executa més ràpid gràcies a la compilació JIT. En algunes proves, la combinació de Static Python i JIT demostra millores de rendiment de fins a 7 vegades en comparació amb CPython estàndard. En moltes situacions, s'estima que els resultats estan a prop d'utilitzar els compiladors MyPyC i Cython.

Font: opennet.ru

Afegeix comentari