Facebook odprtokodni Cinder, razcep CPythona, ki ga uporablja Instagram

Facebook je objavil izvorno kodo za Project Cinder, razcep CPython 3.8.5, glavne referenčne implementacije programskega jezika Python. Cinder se uporablja v Facebookovi proizvodni infrastrukturi za napajanje Instagrama in vključuje optimizacije za izboljšanje učinkovitosti.

Koda je objavljena za razpravo o možnostih prenosa pripravljenih optimizacij v glavno ogrodje CPython in za pomoč drugim projektom, ki sodelujejo pri izboljšanju zmogljivosti CPython. Facebook ne namerava podpirati Cinderja v obliki ločenega odprtokodnega projekta in je koda predstavljena v obliki, v kateri se uporablja v infrastrukturi podjetja, brez dodatnega česanja in dokumentacije. Prav tako ne poskušajo promovirati Cinderja kot alternative CPythonu - glavni cilj razvoja je želja po izboljšanju samega CPythona.

Koda Cinder velja za dokaj zanesljivo in preizkušeno v produkcijskih okoljih, a če se odkrijejo težave, jih boste morali rešiti sami, saj Facebook ne jamči, da se bo odzvala na zunanja sporočila o napakah in zahteve po vleku. Hkrati Facebook ne izključuje konstruktivnega sodelovanja s skupnostjo in je pripravljen razpravljati o idejah, kako narediti Cinder še hitrejši ali kako pospešiti prenos pripravljenih sprememb v glavni del CPython.

Glavne optimizacije, implementirane v Cinder:

  • Vgrajeno predpomnjenje bajtne kode (»senčna bajtna koda«). Bistvo metode je identificirati situacije, v katerih se izvaja tipična opcijska koda, ki jo je mogoče optimizirati, in dinamično zamenjati takšno opcijsko kodo s hitrejšimi specializiranimi možnostmi (na primer zamenjava pogosto klicanih funkcij).
  • Nestrpna sorutinska ocena. Za klice asinhronih funkcij, ki so obdelani takoj (await ne povzroči čakanja in funkcija prej doseže stavek return), je rezultat takšnih funkcij neposredno nadomeščen brez ustvarjanja korutine ali vključevanja zanke dogodkov. V kodi Facebook, ki močno uporablja async/await, optimizacija povzroči približno 5-odstotno pospešitev.
  • Selektivno JIT prevajanje na ravni posameznih metod in funkcij (method-at-a-time). Omogočeno prek možnosti »-X jit« ali spremenljivke okolja PYTHONJIT=1 in vam omogoča, da pospešite izvajanje številnih testov zmogljivosti za 1.5-4-krat. Ker je prevajanje JIT pomembno samo za pogosto izvajane funkcije, ga ni priporočljivo uporabljati za redko uporabljene funkcije, katerih prevajanje lahko samo upočasni izvajanje programa.

    Z možnostjo “-X jit-list-file=/path/to/jitlist.txt” ali spremenljivko okolja “PYTHONJITLISTFILE=/path/to/jitlist.txt” lahko določite datoteko s seznamom funkcij, za katere JIT je mogoče uporabiti (format poti .to.module:funcname ali path.to.module:ClassName.method_name). Seznam funkcij, za katere je treba omogočiti JIT, je mogoče določiti na podlagi rezultatov profiliranja. V prihodnje se pričakuje podpora za dinamično JIT prevajanje na osnovi interne analize pogostosti klicev funkcij, vendar je ob upoštevanju specifike zagona procesov na Instagramu JIT prevajanje primerno tudi za Facebook v začetni fazi.

    JIT najprej pretvori bajtno kodo Python v visokonivojsko vmesno predstavitev (HIR), ki je precej blizu bajtni kodi Python, vendar je zasnovana za uporabo navideznega stroja, ki temelji na registru, namesto na osnovi sklada, uporablja pa tudi informacije o vrsti in dodatne podrobnosti, ki so kritične za delovanje (kot je štetje referenc) . HIR se nato pretvori v obliko SSA (statična ena dodelitev) in gre skozi korake optimizacije, ki upoštevajo rezultate štetja referenc in podatke o porabi pomnilnika. Posledično se ustvari nizkonivojska vmesna predstavitev (LIR), ki je blizu zbirnemu jeziku. Po drugi fazi optimizacij, ki temeljijo na LIR, se navodila za sestavljanje generirajo s knjižnico asmjit.

  • Strogi način za module. Funkcionalnost vključuje tri komponente: Vrsta StrictModule. Statični analizator, ki lahko ugotovi, da izvajanje modula nima vpliva na kodo zunaj tega modula. Nalagalnik modulov, ki ugotovi, da so moduli v strogem načinu (koda podaja »import __strict__«), preveri, ali ni presečišč z drugimi moduli, in naloži stroge module v sys.modules kot objekt StrictModule.
  • Statični Python je eksperimentalni prevajalnik bajtne kode, ki uporablja opombe tipa za ustvarjanje bajtne kode, specifične za vrsto, ki deluje hitreje zahvaljujoč prevajanju JIT. V nekaterih testih kombinacija statičnega Pythona in JIT dokazuje do 7-kratno izboljšanje zmogljivosti v primerjavi s standardnim CPythonom. V mnogih primerih se ocenjuje, da so rezultati blizu uporabe prevajalnikov MyPyC in Cython.

Vir: opennet.ru

Dodaj komentar