A Facebook nyílt forráskódú Cinder, az Instagram által használt CPython ága

A Facebook közzétette a Project Cinder forráskódját, amely a CPython 3.8.5, a Python programozási nyelv fő referencia implementációja. A Cindert a Facebook éles infrastruktúrájában használják az Instagram működtetésére, és a teljesítmény javítása érdekében optimalizálásokat is tartalmaz.

A kódot azért tették közzé, hogy megvitassák az előkészített optimalizálások fő CPython keretrendszerre történő portolásának lehetőségét, és segítsenek a CPython teljesítményének javításában részt vevő egyéb projektekben. A Facebook nem kívánja támogatni a Cindert külön nyílt forráskódú projekt formájában, és a kód abban a formában jelenik meg, ahogyan azt a vállalat infrastruktúrájában használják, további átfésülés és dokumentáció nélkül. A Cindert sem próbálják népszerűsíteni a CPython alternatívájaként – a fejlesztés fő célja magának a CPythonnak a tökéletesítése.

A Cinder kódot meglehetősen megbízhatónak és éles környezetben tesztelték, de ha problémákat azonosítanak, akkor ezeket Önnek kell megoldania, mivel a Facebook nem garantálja, hogy válaszol a külső hibaüzenetekre és a lehívási kérésekre. A Facebook ugyanakkor nem zárja ki a közösséggel való konstruktív együttműködést, és kész megvitatni ötleteket, hogyan lehetne még gyorsabban Cindert felgyorsítani, vagy hogyan lehetne felgyorsítani az előkészített változtatások átvitelét a CPython fő részére.

A Cinderben végrehajtott fő optimalizálások:

  • A bájtkód soron belüli gyorsítótárazása („árnyékbájtkód”). A módszer lényege, hogy azonosítsa azokat a helyzeteket, amikor egy tipikus, optimalizálható műveleti kódot hajtanak végre, és egy ilyen műveleti kódot dinamikusan lecserélik gyorsabb speciális opciókra (például gyakran hívott függvények cseréjére).
  • Mohó korutin értékelés. Azonnal feldolgozott aszinkron függvényhívásoknál (a várakozás nem eredményez várakozást, és a függvény korábban éri el a return utasítást), az ilyen függvények eredménye közvetlenül behelyettesítésre kerül, korutin létrehozása vagy eseményhurok bevonása nélkül. Az aszinkron/várakozást erősen használó Facebook-kódban az optimalizálás körülbelül 5%-os gyorsulást eredményez.
  • Szelektív JIT összeállítás az egyes módszerek és funkciók szintjén (method-at-a-time). Engedélyezve a „-X jit” opcióval vagy a PYTHONJIT=1 környezeti változóval, és lehetővé teszi számos teljesítményteszt végrehajtásának 1.5-4-szeres gyorsítását. Mivel a JIT fordítás csak a gyakran végrehajtott függvényeknél releváns, nem célszerű olyan ritkán használt függvényeknél használni, amelyek fordítási többlete csak lassíthatja a programvégrehajtást.

    A „-X jit-list-file=/path/to/jitlist.txt” opcióval vagy a „PYTHONJITLISTFILE=/path/to/jitlist.txt” környezeti változóval megadhat egy fájlt azon funkciók listájával, amelyekhez a JIT. használható (elérési út .to.module:funcname vagy path.to.module:ClassName.method_name). A profilalkotás eredményei alapján meghatározható azon funkciók listája, amelyekhez a JIT-t engedélyezni kell. A jövőben a függvényhívások gyakoriságának belső elemzése alapján várható a dinamikus JIT-összeállítás támogatása, de az Instagramon történő indítási folyamatok sajátosságait figyelembe véve a JIT-összeállítás kezdeti szakaszban a Facebook számára is megfelelő.

    A JIT először konvertálja a Python bájtkódot magas szintű köztes reprezentációvá (HIR), amely meglehetősen közel áll a Python bájtkódhoz, de úgy tervezték, hogy egy regiszter alapú virtuális gépet használjon a verem alapú helyett, valamint típusinformációkat és további teljesítménykritikus részletek (például referenciaszámlálás) . A HIR ezután SSA (static single assignment) formává alakul, és optimalizálási lépéseken megy keresztül, amelyek figyelembe veszik a referenciaszámlálás eredményeit és a memóriafogyasztási adatokat. Ennek eredményeként egy alacsony szintű köztes reprezentáció (LIR) jön létre, közel az assembly nyelvhez. A LIR-alapú optimalizálás újabb fázisa után az asmjit könyvtár használatával összeállítási utasítások jönnek létre.

  • Szigorú mód a modulokhoz. A funkció három összetevőből áll: Type StrictModule. Statikus elemző, amely képes meghatározni, hogy egy modul végrehajtása nincs hatással a modulon kívüli kódra. Egy modulbetöltő, amely megállapítja, hogy a modulok szigorú módban vannak (a kód az „import __strict__” értéket adja meg), ellenőrzi, hogy nincsenek-e metszéspontok más modulokkal, és szigorú modulokat tölt be a sys.modules-ba StrictModule objektumként.
  • A Static Python egy kísérleti bájtkód-fordító, amely típusjegyzeteket használ a típusspecifikus bájtkód létrehozásához, amely a JIT-fordításnak köszönhetően gyorsabban fut. Egyes tesztekben a Static Python és a JIT kombinációja akár hétszeres teljesítményjavulást mutat a szabványos CPythonhoz képest. A becslések szerint sok esetben az eredmények közel állnak a MyPyC és Cython fordítók használatához.

Forrás: opennet.ru

Hozzászólás