Facebook open sourced Cinder, isang tinidor ng CPython na ginagamit ng Instagram

Inilathala ng Facebook ang source code para sa Project Cinder, isang tinidor ng CPython 3.8.5, ang pangunahing reference na pagpapatupad ng Python programming language. Ang Cinder ay ginagamit sa imprastraktura ng produksyon ng Facebook upang palakasin ang Instagram at may kasamang mga pag-optimize upang mapabuti ang pagganap.

Inilathala ang code upang talakayin ang posibilidad ng pag-port ng mga inihandang pag-optimize sa pangunahing balangkas ng CPython at upang matulungan ang iba pang mga proyektong kasangkot sa pagpapabuti ng pagganap ng CPython. Hindi nilayon ng Facebook na suportahan si Cinder sa anyo ng isang hiwalay na open source na proyekto at ang code ay ipinakita sa anyo kung saan ito ginagamit sa imprastraktura ng kumpanya, nang walang karagdagang pagsusuklay at dokumentasyon. Hindi rin nila sinusubukang isulong ang Cinder bilang alternatibo sa CPython - ang pangunahing layunin ng pag-unlad ay ang pagnanais na mapabuti ang CPython mismo.

Ang Cinder code ay kilala bilang medyo maaasahan at nasubok sa mga kapaligiran ng produksyon, ngunit kung natukoy ang mga problema, kakailanganin mong lutasin ang mga ito sa iyong sarili, dahil hindi ginagarantiya ng Facebook na tutugon ito sa mga panlabas na mensahe ng error at mga kahilingan sa paghila. Kasabay nito, hindi ibinubukod ng Facebook ang nakabubuo na pakikipagtulungan sa komunidad at handang talakayin ang mga ideya kung paano pabilisin ang Cinder o kung paano pabilisin ang paglipat ng mga inihandang pagbabago sa pangunahing bahagi ng CPython.

Mga pangunahing pag-optimize na ipinatupad sa Cinder:

  • Inline na pag-cache ng bytecode ("shadow bytecode"). Ang kakanyahan ng pamamaraan ay upang tukuyin ang mga sitwasyon kung saan ang isang tipikal na opcode ay isinasagawa na maaaring i-optimize, at dynamic na palitan ang naturang opcode ng mas mabilis na espesyal na mga opsyon (halimbawa, pagpapalit ng madalas na tinatawag na mga function).
  • Sabik na pagsusuri sa coroutine. Para sa async function na mga tawag na naproseso kaagad (ang paghihintay ay hindi nagreresulta sa isang paghihintay at ang function ay umabot sa return statement nang mas maaga), ang resulta ng naturang mga function ay direktang pinapalitan nang hindi gumagawa ng coroutine o kinasasangkutan ng isang event loop. Sa Facebook code na gumagamit ng async/naghihintay, ang pag-optimize ay nagreresulta sa isang speedup na humigit-kumulang 5%.
  • Selective JIT compilation sa antas ng mga indibidwal na pamamaraan at function (paraan-sa-isang-panahon). Naka-enable sa pamamagitan ng opsyong “-X jit” o ang PYTHONJIT=1 environment variable at nagbibigay-daan sa iyong pabilisin ang pagsasagawa ng maraming performance test nang 1.5-4 na beses. Dahil ang JIT compilation ay may kaugnayan lamang para sa mga madalas na pinaandar na function, hindi ipinapayong gamitin ito para sa mga bihirang ginagamit na function, ang compilation overhead na kung saan ay maaari lamang makapagpabagal sa pagpapatupad ng program.

    Sa pamamagitan ng opsyong “-X jit-list-file=/path/to/jitlist.txt” o ang environment variable na “PYTHONJITLISTFILE=/path/to/jitlist.txt” maaari kang tumukoy ng file na may listahan ng mga function kung saan JIT maaaring gamitin (path format .to.module:funcname o path.to.module:ClassName.method_name). Maaaring matukoy ang listahan ng mga function kung saan dapat paganahin ang JIT batay sa mga resulta ng profiling. Sa hinaharap, ang suporta para sa dynamic na JIT compilation ay inaasahan batay sa panloob na pagsusuri ng dalas ng mga function na tawag, ngunit isinasaalang-alang ang mga detalye ng mga proseso ng paglulunsad sa Instagram, ang JIT compilation ay angkop din para sa Facebook sa paunang yugto.

    Ang JIT ay unang nag-convert ng Python bytecode sa isang high-level intermediate representation (HIR), na medyo malapit sa Python bytecode, ngunit idinisenyo upang gumamit ng isang register-based virtual machine sa halip na isang stack-based, at gumagamit din ng uri ng impormasyon at karagdagang mga detalyeng kritikal sa pagganap (tulad ng pagbibilang ng sanggunian) . Ang HIR ay iko-convert sa form na SSA (static single assignment) at dumaan sa mga hakbang sa pag-optimize na isinasaalang-alang ang mga resulta ng pagbibilang ng reference at data ng pagkonsumo ng memorya. Bilang resulta, nabuo ang isang mababang antas ng intermediate na representasyon (LIR), malapit sa wika ng pagpupulong. Pagkatapos ng isa pang yugto ng mga pag-optimize na nakabatay sa LIR, ang mga tagubilin sa pagpupulong ay nabuo gamit ang asmjit library.

  • Mahigpit na mode para sa mga module. Kasama sa functionality ang tatlong bahagi: Uri ng StrictModule. Isang static na analyzer na maaaring matukoy na ang pagpapatupad ng isang module ay walang epekto sa code sa labas ng module na iyon. Isang module loader na tumutukoy na ang mga module ay nasa strict mode (ang code ay tumutukoy sa "import __strict__"), nagsusuri ng kawalan ng mga intersection sa iba pang mga module, at naglo-load ng mga mahigpit na module sa sys.modules bilang isang object ng StrictModule.
  • Ang Static Python ay isang pang-eksperimentong bytecode compiler na gumagamit ng mga uri ng anotasyon upang makabuo ng partikular na uri ng bytecode na tumatakbo nang mas mabilis salamat sa JIT compilation. Sa ilang mga pagsubok, ang kumbinasyon ng Static Python at JIT ay nagpapakita ng mga pagpapahusay sa pagganap ng hanggang 7 beses kumpara sa karaniwang CPython. Sa maraming sitwasyon, ang mga resulta ay tinatantya na malapit sa paggamit ng MyPyC at Cython compiler.

Pinagmulan: opennet.ru

Magdagdag ng komento