ProHoster > Blogs > AdministrÄcija > KÄ mÄs pÄrtulkojÄm 10 miljonus C++ koda rindiÅu uz C++14 standartu (un pÄc tam uz C++17)
KÄ mÄs pÄrtulkojÄm 10 miljonus C++ koda rindiÅu uz C++14 standartu (un pÄc tam uz C++17)
Pirms kÄda laika (2016. gada rudenÄ«), izstrÄdÄjot 1C:Enterprise tehnoloÄ£iju platformas nÄkamo versiju, izstrÄdes komandÄ radÄs jautÄjums par jaunÄ standarta atbalstÄ«Å”anu. C ++ 14 mÅ«su kodÄ. PÄreja uz jaunu standartu, kÄ mÄs pieÅÄmÄm, ļautu mums daudz ko uzrakstÄ«t elegantÄk, vienkÄrÅ”Äk un uzticamÄk, kÄ arÄ« vienkÄrÅ”otu koda atbalstu un uzturÄÅ”anu. Un Ŕķiet, ka tulkojumÄ nav nekÄ ÄrkÄrtÄja, ja ne koda bÄzes mÄrogs un mÅ«su koda Ä«paÅ”Äs iezÄ«mes.
Tiem, kas nezina, 1C:Enterprise ir vide Ätrai starpplatformu biznesa lietojumprogrammu izstrÄdei un izpildlaikam to izpildei dažÄdÄs operÄtÄjsistÄmÄs un DBVS. KopumÄ produkts satur:
MÄs cenÅ”amies pÄc iespÄjas vairÄk rakstÄ«t vienu un to paÅ”u kodu dažÄdÄm operÄtÄjsistÄmÄm - servera kodu bÄze ir 99% kopÄ«ga, klienta kodu bÄze ir aptuveni 95%. 1C:Enterprise tehnoloÄ£iju platforma galvenokÄrt ir rakstÄ«ta C++ valodÄ, un aptuvenÄs koda Ä«paŔības ir norÄdÄ«tas zemÄk:
10 miljoni C++ koda rindiÅu,
14 tūkstoŔi failu,
60 tūkstoŔi nodarbību,
pusmiljons metožu.
Un visas Ŕīs lietas bija jÄtulko C++14 valodÄ. Å odien mÄs jums pastÄstÄ«sim, kÄ mÄs to izdarÄ«jÄm un ar ko saskÄrÄmies Å”ajÄ procesÄ.
Atruna
Viss, kas rakstÄ«ts zemÄk par lÄnu/Ätro darbu, (ne) lielo atmiÅas patÄriÅu, ievieÅ”ot standarta klases dažÄdÄs bibliotÄkÄs, nozÄ«mÄ vienu: tas attiecas uz MUMS. PilnÄ«gi iespÄjams, ka standarta implementÄcijas bÅ«s vispiemÄrotÄkÄs jÅ«su uzdevumiem. MÄs sÄkÄm no saviem uzdevumiem: ÅÄmÄm datus, kas bija raksturÄ«gi mÅ«su klientiem, palaidÄm tiem tipiskus scenÄrijus, apskatÄ«jÄm veiktspÄju, patÄrÄtÄs atmiÅas apjomu utt. un analizÄjÄm, vai mÄs un mÅ«su klienti esam apmierinÄti ar Å”Ädiem rezultÄtiem vai nÄ. . Un viÅi rÄ«kojÄs atkarÄ«bÄ no.
Kas mums bija
SÄkotnÄji mÄs rakstÄ«jÄm kodu platformai 1C: Enterprise 8, izmantojot Microsoft Visual Studio. Projekts sÄkÄs 2000. gadu sÄkumÄ, un mums bija tikai Windows versija. Protams, kopÅ” tÄ laika kods ir aktÄ«vi izstrÄdÄts, daudzi mehÄnismi ir pilnÄ«bÄ pÄrrakstÄ«ti. Bet kods tika uzrakstÄ«ts pÄc 1998. gada standarta, un, piemÄram, mÅ«su taisnleÅÄ·a iekavas tika atdalÄ«tas ar atstarpÄm, lai kompilÄcija izdotos, piemÄram:
vector<vector<int> > IntV;
2006. gadÄ, izlaižot platformas versiju 8.1, mÄs sÄkÄm atbalstÄ«t Linux un pÄrgÄjÄm uz treÅ”Äs puses standarta bibliotÄku. STLPort. Viens no pÄrejas iemesliem bija darbs ar platÄm lÄ«nijÄm. SavÄ kodÄ mÄs izmantojam std::wstring, kura pamatÄ ir wchar_t veids. TÄ lielums operÄtÄjsistÄmÄ Windows ir 2 baiti, un Linux noklusÄjuma izmÄrs ir 4 baiti. Tas izraisÄ«ja mÅ«su binÄro protokolu nesaderÄ«bu starp klientu un serveri, kÄ arÄ« dažÄdus pastÄvÄ«gus datus. Izmantojot gcc opcijas, var norÄdÄ«t, ka arÄ« wchar_t izmÄrs kompilÄcijas laikÄ ir 2 baiti, bet tad var aizmirst par standarta bibliotÄkas izmantoÅ”anu no kompilatora, jo tas izmanto glibc, kas savukÄrt tiek kompilÄts 4 baitu wchar_t. Citi iemesli bija labÄka standarta klaÅ”u ievieÅ”ana, atbalsts hash tabulÄm un pat konteineru iekÅ”puses pÄrvietoÅ”anas semantikas emulÄcija, ko mÄs aktÄ«vi izmantojÄm. Un vÄl viens iemesls, kÄ saka, pÄdÄjais, bet ne mazÄk svarÄ«gais, bija stÄ«gu izpildÄ«jums. Mums bija sava stÄ«gu klase, jo... MÅ«su programmatÅ«ras specifikas dÄļ virkÅu darbÄ«bas tiek izmantotas ļoti plaÅ”i, un mums tas ir ļoti svarÄ«gi.
MÅ«su virkne ir balstÄ«ta uz virkÅu optimizÄcijas idejÄm, kas izteiktas 2000. gadu sÄkumÄ Andrejs Aleksandresku. VÄlÄk, kad Aleksandresku strÄdÄja Facebook, pÄc viÅa ierosinÄjuma Facebook dzinÄjÄ tika izmantota lÄ«nija, kas darbojÄs pÄc lÄ«dzÄ«giem principiem (sk. bibliotÄku muļķība).
MÅ«su lÄ«nija izmantoja divas galvenÄs optimizÄcijas tehnoloÄ£ijas:
ÄŖsÄm vÄrtÄ«bÄm tiek izmantots iekÅ”Äjais buferis paÅ”Ä virknes objektÄ (nav nepiecieÅ”ama papildu atmiÅas pieŔķirÅ”ana).
Visiem pÄrÄjiem tiek izmantota mehÄnika KopÄt uz rakstÄ«Å”anas. Virknes vÄrtÄ«ba tiek saglabÄta vienuviet, un pieŔķirÅ”anas/modifikÄcijas laikÄ tiek izmantots atsauces skaitÄ«tÄjs.
Lai paÄtrinÄtu platformas kompilÄciju, mÄs izslÄdzÄm straumes ievieÅ”anu no mÅ«su STLPort varianta (kuru mÄs neizmantojÄm), tas mums nodroÅ”inÄja par aptuveni 20% ÄtrÄku kompilÄciju. PÄc tam mums bija jÄizmanto ierobežota izmantoÅ”ana PalielinÄt. Boost intensÄ«vi izmanto straumi, jo Ä«paÅ”i tÄs pakalpojumu API (piemÄram, reÄ£istrÄÅ”anai), tÄpÄc mums tas bija jÄmaina, lai noÅemtu straumes izmantoÅ”anu. Tas savukÄrt mums apgrÅ«tinÄja migrÄÅ”anu uz jaunÄm Boost versijÄm.
treŔais ceļŔ
PÄrejot uz C++14 standartu, mÄs apsvÄrÄm Å”Ädas iespÄjas:
Jauniniet STLPort, kuru mÄs modificÄjÄm, uz C++14 standartu. Variants ir ļoti grÅ«ts, jo... STLPort atbalsts tika pÄrtraukts 2010. gadÄ, un mums paÅ”iem bÅ«tu jÄizveido viss tÄ kods.
PÄreja uz citu STL ievieÅ”anu, kas ir saderÄ«ga ar C++14. Ir ļoti vÄlams, lai Ŕī ievieÅ”ana bÅ«tu operÄtÄjsistÄmai Windows un Linux.
KompilÄjot katrai OS, izmantojiet atbilstoÅ”ajÄ kompilatorÄ iebÅ«vÄto bibliotÄku.
Pirmais variants tika pilnÄ«bÄ noraidÄ«ts pÄrÄk daudz darba dÄļ.
KÄdu laiku domÄjÄm par otro variantu; uzskatÄ«ts par kandidÄtu libc++, bet tajÄ laikÄ tas nedarbojÄs operÄtÄjsistÄmÄ Windows. Lai portÄtu libc++ uz Windows, jums bÅ«s daudz jÄstrÄdÄ - piemÄram, paÅ”am jÄraksta viss, kas saistÄ«ts ar pavedieniem, pavedienu sinhronizÄciju un atomitÄti, jo Å”ajÄs jomÄs tiek izmantots libc++ POSIX API.
Un mÄs izvÄlÄjÄmies treÅ”o ceļu.
PÄreja
TÄtad mums bija jÄaizstÄj STLPort lietoÅ”ana ar atbilstoÅ”o kompilatoru bibliotÄkÄm (Visual Studio 2015 operÄtÄjsistÄmai Windows, gcc 7 operÄtÄjsistÄmai Linux, clang 8 operÄtÄjsistÄmai macOS).
Par laimi, mÅ«su kods tika rakstÄ«ts galvenokÄrt saskaÅÄ ar vadlÄ«nijÄm un tajÄ netika izmantoti visÄdi gudri triki, tÄpÄc migrÄcija uz jaunÄm bibliotÄkÄm noritÄja salÄ«dzinoÅ”i raiti, izmantojot skriptus, kas aizstÄja veidu, klaÅ”u, nosaukumvietu nosaukumus un ietver avotÄ. failus. MigrÄcija skÄra 10 000 avota failu (no 14 000). wchar_t tika aizstÄts ar char16_t; mÄs nolÄmÄm atteikties no wchar_t lietoÅ”anas, jo char16_t visÄs operÄtÄjsistÄmÄs aizÅem 2 baitus un nesabojÄ koda saderÄ«bu starp Windows un Linux.
Bija daži nelieli piedzÄ«vojumi. PiemÄram, STLPort iterators var tikt netieÅ”i nodots rÄdÄ«tÄjam uz elementu, un dažÄs mÅ«su koda vietÄs tas tika izmantots. JaunajÄs bibliotÄkÄs to vairs nebija iespÄjams izdarÄ«t, un Å”ie fragmenti bija jÄanalizÄ un jÄpÄrraksta manuÄli.
TÄtad koda migrÄcija ir pabeigta, kods ir apkopots visÄm operÄtÄjsistÄmÄm. Ir pienÄcis laiks testiem.
PÄrbaudes pÄc pÄrejas uzrÄdÄ«ja veiktspÄjas kritumu (dažÄs vietÄs lÄ«dz 20-30%) un atmiÅas patÄriÅa pieaugumu (lÄ«dz 10-15%), salÄ«dzinot ar veco koda versiju. Tas jo Ä«paÅ”i bija saistÄ«ts ar standarta stÄ«gu neoptimÄlo veiktspÄju. TÄpÄc atkal nÄcÄs izmantot savu, nedaudz pÄrveidoto lÄ«niju.
Tika atklÄta arÄ« interesanta konteineru ievieÅ”anas iezÄ«me iegultajÄs bibliotÄkÄs: tukÅ”a (bez elementiem) std::map un std::set no iebÅ«vÄtajÄm bibliotÄkÄm pieŔķir atmiÅu. Un ievieÅ”anas pazÄ«mju dÄļ dažÄs vietÄs kodÄ tiek izveidots diezgan daudz tukÅ”u Å”Äda veida konteineru. Standarta atmiÅas konteineri ir atvÄlÄti nedaudz, vienam saknes elementam, bet mums tas izrÄdÄ«jÄs kritiski - vairÄkos scenÄrijos mÅ«su veiktspÄja ievÄrojami samazinÄjÄs un atmiÅas patÄriÅÅ” palielinÄjÄs (salÄ«dzinot ar STLPort). TÄpÄc savÄ kodÄ mÄs aizstÄjÄm Å”os divu veidu konteinerus no iebÅ«vÄtajÄm bibliotÄkÄm ar to ievieÅ”anu no Boost, kur Å”iem konteineriem nebija Ŕīs funkcijas, un tas atrisinÄja problÄmu ar palÄninÄÅ”anos un palielinÄtu atmiÅas patÄriÅu.
KÄ tas bieži notiek pÄc liela mÄroga izmaiÅÄm lielos projektos, pirmÄ avota koda iterÄcija nedarbojÄs bez problÄmÄm, un Å”eit jo Ä«paÅ”i noderÄja iteratoru atkļūdoÅ”anas atbalsts Windows ievieÅ”anÄ. Soli pa solim mÄs virzÄmies uz priekÅ”u, un lÄ«dz 2017. gada pavasarim (versija 8.3.11 1C:Enterprise) migrÄÅ”ana tika pabeigta.
RezultÄti
PÄreja uz C++14 standartu mums aizÅÄma aptuveni 6 mÄneÅ”us. LielÄko daļu laika pie projekta strÄdÄja viens (bet ļoti augsti kvalificÄts) izstrÄdÄtÄjs, un beigu posmÄ pievienojÄs par konkrÄtÄm jomÄm atbildÄ«go komandu pÄrstÄvji - UI, serveru klasteris, izstrÄdes un administrÄÅ”anas rÄ«ki utt.
PÄreja ievÄrojami vienkÄrÅ”oja mÅ«su darbu pie migrÄcijas uz jaunÄkajÄm standarta versijÄm. TÄdÄjÄdi versija 1C:Enterprise 8.3.14 (izstrÄdÄ, izlaiÅ”ana paredzÄta nÄkamÄ gada sÄkumÄ) jau ir pÄrcelta uz standartu C++17.
PÄc migrÄcijas izstrÄdÄtÄjiem ir vairÄk iespÄju. Ja agrÄk mums bija sava modificÄtÄ STL versija un viena std nosaukumvieta, tad tagad mums ir standarta klases no iebÅ«vÄto kompilatoru bibliotÄkÄm std nosaukumvietÄ, stdx nosaukumvietÄ - mÅ«su rindas un konteineri, kas optimizÄti mÅ«su uzdevumiem, pastiprinÄjumÄ - jaunÄkÄ pastiprinÄÅ”anas versija. Un izstrÄdÄtÄjs izmanto tÄs klases, kas ir optimÄli piemÄrotas viÅa problÄmu risinÄÅ”anai.
PÄrvietoÅ”anÄs konstruktoru āvietÄjÄā ievieÅ”ana palÄ«dz arÄ« attÄ«stÄ«bÄ (pÄrvietot konstruktorus) vairÄkÄm klasÄm. Ja klasei ir pÄrvietoÅ”anas konstruktors un Ŕī klase ir ievietota konteinerÄ, tad STL optimizÄ elementu kopÄÅ”anu konteinera iekÅ”ienÄ (piemÄram, kad konteiners tiek paplaÅ”inÄts un nepiecieÅ”ams mainÄ«t ietilpÄ«bu un pÄrdalÄ«t atmiÅu).
Lidot ziedi
IespÄjams, visnepatÄ«kamÄkÄs (bet ne kritiskÄs) migrÄcijas sekas ir tÄs, ka mÄs saskaramies ar apjoma pieaugumu obj faili, un pilns bÅ«vÄÅ”anas rezultÄts ar visiem starpfailiem sÄka aizÅemt 60ā70 GB. Å Äda uzvedÄ«ba ir saistÄ«ta ar mÅ«sdienu standarta bibliotÄku Ä«patnÄ«bÄm, kuras ir kļuvuÅ”as mazÄk kritiskas pret Ä£enerÄto pakalpojumu failu lielumu. Tas neietekmÄ kompilÄtÄs lietojumprogrammas darbÄ«bu, taÄu tas rada vairÄkas neÄrtÄ«bas izstrÄdÄ, jo Ä«paÅ”i palielina kompilÄcijas laiku. Pieaug arÄ« prasÄ«bas pÄc brÄ«vas diska vietas build serveros un izstrÄdÄtÄju iekÄrtÄs. MÅ«su izstrÄdÄtÄji paralÄli strÄdÄ pie vairÄkÄm platformas versijÄm, un simtiem gigabaitu starpposma failu dažkÄrt rada grÅ«tÄ«bas viÅu darbÄ. ProblÄma ir nepatÄ«kama, bet ne kritiska; pagaidÄm esam atlikuÅ”i tÄs risinÄÅ”anu. MÄs apsveram tehnoloÄ£iju kÄ vienu no iespÄjÄm tÄs risinÄÅ”anai vienotÄ«bas veidoÅ”ana (jo Ä«paÅ”i Google to izmanto, izstrÄdÄjot pÄrlÅ«ku Chrome).