Facebook адкрыў код Cinder, форка CPython, які выкарыстоўваецца ў Instagram

Кампанія Facebook апублікавала зыходныя тэксты праекту Cinder, які развівае адгалінаванне ад CPython 3.8.5, асноўнай эталоннай рэалізацыі мовы праграмавання Python. Cinder прымяняецца ў рабочай інфраструктуры Facebook для забеспячэння функцыянавання сэрвісу Instagram і ўключае аптымізацыі для павышэння прадукцыйнасці.

Код апублікаваны для абмеркавання магчымасці пераносу падрыхтаваных аптымізацый у асноўны склад CPython і для дапамогі іншым праектам, якія займаюцца павышэннем прадукцыйнасці CPython. Facebook не збіраецца падтрымліваць Cinder у форме асобнага адкрытага праекта і код прадстаўлены ў тым выглядзе, у якім выкарыстоўваецца ў інфраструктуры кампаніі, без дадатковага прычэсвання і дакументавання. Cinder таксама не спрабуюць прасоўваць як альтэрнатыву CPython - асноўнай мэтай распрацоўкі з'яўляецца жаданне палепшыць сам CPython.

Код Cinder адзначаецца як дастаткова надзейны і правераны ў працоўных асяродках, але ў выпадку выяўлення праблем іх прыйдзецца вырашаць самастойна, бо Facebook не гарантуе, што будзе рэагаваць на вонкавыя паведамленні аб памылках і pull-запыты. Пры гэтым Fecebook не выключае канструктыўнае супрацоўніцтва з супольнасцю і гатовы абмеркаваць ідэі як зрабіць Cinder яшчэ хутчэй ці як паскорыць перанос падрыхтаваных змен у асноўны склад CPython.

Асноўныя аптымізацыі, рэалізаваныя ў Cinder:

  • Inline-кэшаванне байткода («shadow bytecode»). Сутнасць метаду ў выяўленні сітуацый выканання тыпавога опкода, якія можна апітымізаваць, і дынамічнай замене падобнага опкода на хутчэйшыя спецыялізаваныя варыянты (напрыклад, замена часта выкліканых функцый).
  • Актыўны вылічэнне супраграм (Eager coroutine evaluation). Для выклікаў async-функцый, якія адразу апрацоўваюцца (await не прыводзіць да чакання і функцыя дасягае аператара return раней), вынік падобных функцый напрамую падстаўляецца без стварэння супраграмы і без прыцягнення цыклу апрацоўкі падзей. У ужывальным у Facebook кодзе, у якім актыўна выкарыстоўваецца async/await, аптымізацыя прыводзіць да паскарэння прыкладна на 5%.
  • Выбарачная JIT-кампіляцыя на ўзроўні асобных метадаў і функцый (method-at-a-time). Уключаецца праз опцыю "-X jit" або зменную асяроддзі PYTHONJIT=1 і дазваляе паскорыць выкананне шматлікіх тэстаў прадукцыйнасці ў 1.5-4 разу. Бо JIT-кампіляцыя актуальная толькі для часта выкананых функцый, немэтазгодна ўжываць яе для рэдка выкарыстоўваных функцый, накладныя выдаткі на кампіляцыю якіх могуць толькі запаволіць выкананне праграмы.

    Праз опцыю "-X jit-list-file=/path/to/jitlist.txt" або зменную асяроддзі "PYTHONJITLISTFILE=/path/to/jitlist.txt" можна пазначыць файл са спісам функцый, для якіх можна выкарыстоўваць JIT (фармат path .to.module:funcname ці path.to.module:ClassName.method_name). Спіс функцый для якіх варта ўключыць JIT можна вызначыць на аснове вынікаў прафілявання. У будучыні чакаецца падтрымка дынамічнай JIT-кампіляцыі на аснове ўнутранага аналізу частаты выкліку функцый, але з улікам спецыфікі запуску працэсаў у Instagram, для Facebook падыходзіць і JIT-кампіляцыя на пачатковым этапе.

    JIT спачатку пераўтворыць байткод Python у высокаўзроўневы прамежкавы паказ (HIR), якое досыць блізка да байткоду Python, але разлічана на выкарыстанне рэгістравай віртуальнай машыны, замест стэкавай, а таксама выкарыстоўвае інфармацыю пра тыпы і дадатковыя дэталі, важныя для прадукцыйнасці (напрыклад, . HIR затым пераўтворыцца ў форму SSA (static single assignment) і праходзіць стадыі аптымізацыі, якія ўлічваюць вынікі падліку спасылак і дадзеныя аб спажыванні памяці. У выніку генеруецца нізкаўзроўневае прамежкавае ўяўленне (LIR), блізкае да мовы асэмблер. Пасля яшчэ адной фазы аптымізацый на аснове LIR пры дапамозе бібліятэкі asmjit генеруюцца асэмблерныя інструкцыі.

  • Рэжым strict для модуляў. Функцыянальнасць уключае тры кампаненты : Тып StrictModule. Статычны аналізатар, здольны вызначыць, што выкананне модуля не ўплывае на код за межамі гэтага модуля. Загрузнік модуляў, які вызначае, што модулі перакладзеныя ў рэжым strict (у кодзе паказваецца "import __strict__"), правяральны адсутнасць скрыжаванняў з іншымі модулямі і які загружае strict-модулі ў sys.modules у выглядзе аб'екта StrictModule.
  • Static Python - эксперыментальны кампілятар байткода, які выкарыстоўвае анатацыі тыпаў для генерацыі байткода, спецыфічнага для кожнага тыпу і выкананага хутчэй дзякуючы прымяненню JIT-кампіляцыі. У некаторых тэстах спалучэнне Static Python і JIT дэманструе павышэнне прадукцыйна да 7 разоў, у параўнанні з тыпавым CPython. У шматлікіх сітуацыях вынікі ацэньваюцца як блізкія да ўжывання кампілятараў MyPyC і Cython.

Крыніца: opennet.ru

Дадаць каментар