Facebook med öppen källkod Cinder, en gaffel av CPython som används av Instagram

Facebook har publicerat källkoden för Project Cinder, en gaffel av CPython 3.8.5, den huvudsakliga referensimplementeringen av Python-programmeringsspråket. Cinder används i Facebooks produktionsinfrastruktur för att driva Instagram och inkluderar optimeringar för att förbättra prestandan.

Koden publiceras för att diskutera möjligheten att porta de förberedda optimeringarna till CPythons huvudramverk och för att hjälpa andra projekt som är involverade i att förbättra CPython-prestanda. Facebook har inte för avsikt att stödja Cinder i form av ett separat open source-projekt och koden presenteras i den form den används i företagets infrastruktur, utan ytterligare kamning och dokumentation. De försöker inte heller marknadsföra Cinder som ett alternativ till CPython - huvudmålet med utvecklingen är önskan att förbättra själva CPython.

Cinder-koden noteras som ganska tillförlitlig och testad i produktionsmiljöer, men om problem upptäcks måste du lösa dem själv, eftersom Facebook inte garanterar att den kommer att svara på externa felmeddelanden och pull-förfrågningar. Samtidigt utesluter inte Facebook konstruktivt samarbete med communityn och är redo att diskutera idéer om hur man gör Cinder ännu snabbare eller hur man kan påskynda överföringen av förberedda ändringar till huvuddelen av CPython.

Huvudsakliga optimeringar implementerade i Cinder:

  • Inline cachning av bytekod ("skuggbytekod"). Kärnan i metoden är att identifiera situationer där en typisk op-kod exekveras som kan optimeras, och att dynamiskt ersätta en sådan op-kod med snabbare specialiserade alternativ (till exempel att ersätta ofta anropade funktioner).
  • Ivrig coroutine utvärdering. För asynkronfunktionsanrop som behandlas omedelbart (await resulterar inte i en wait och funktionen når return-satsen tidigare), ersätts resultatet av sådana funktioner direkt utan att skapa en coroutine eller involvera en händelseloop. I Facebook-kod som flitigt använder async/await resulterar optimeringen i en speedup på cirka 5%.
  • Selektiv JIT-sammanställning på nivån för individuella metoder och funktioner (metod-i-sänder). Aktiverad via alternativet "-X jit" eller miljövariabeln PYTHONJIT=1 och låter dig påskynda utförandet av många prestandatester med 1.5-4 gånger. Eftersom JIT-kompilering endast är relevant för ofta körda funktioner, är det inte tillrådligt att använda det för sällan använda funktioner, vars kompileringsoverhead bara kan sakta ner programexekveringen.

    Via alternativet “-X jit-list-file=/path/to/jitlist.txt” eller miljövariabeln “PYTHONJITLISTFILE=/path/to/jitlist.txt” kan du ange en fil med en lista över funktioner för vilka JIT kan användas (sökvägsformat .to.module:funcname eller path.to.module:ClassName.method_name). Listan över funktioner för vilka JIT ska aktiveras kan bestämmas baserat på profileringsresultaten. I framtiden förväntas stöd för dynamisk JIT-kompilering baserat på intern analys av frekvensen av funktionsanrop, men med hänsyn till detaljerna för att lansera processer på Instagram är JIT-kompilering även lämplig för Facebook i det inledande skedet.

    JIT konverterar först Python-bytecode till en högnivå-mellanrepresentation (HIR), som är ganska nära Python-bytecode, men är designad för att använda en registerbaserad virtuell maskin istället för en stackbaserad, och använder även typinformation och ytterligare prestandakritiska detaljer (som referensräkning) . HIR konverteras sedan till SSA (static single assignment) form och går igenom optimeringssteg som tar hänsyn till referensräkningsresultat och minnesförbrukningsdata. Som ett resultat genereras en lågnivå mellanrepresentation (LIR) nära assemblerspråk. Efter ytterligare en fas av LIR-baserade optimeringar genereras monteringsinstruktioner med hjälp av asmjit-biblioteket.

  • Strikt läge för moduler. Funktionen inkluderar tre komponenter: Typ StrictModule. En statisk analysator som kan avgöra att exekveringen av en modul inte har någon inverkan på kod utanför den modulen. En modulladdare som bestämmer att modulerna är i strikt läge (koden specificerar "import __strict__"), kontrollerar frånvaron av korsningar med andra moduler och laddar strikta moduler till sys.modules som ett StrictModule-objekt.
  • Static Python är en experimentell bytekodkompilator som använder typkommentarer för att generera typspecifik bytekod som körs snabbare tack vare JIT-kompilering. I vissa tester visar kombinationen av Static Python och JIT prestandaförbättringar på upp till 7 gånger jämfört med standard CPython. I många situationer uppskattas resultaten vara nära att använda MyPyC- och Cython-kompilatorerna.

Källa: opennet.ru

Lägg en kommentar