Jinsi tulivyotafsiri mistari milioni 10 ya msimbo wa C++ hadi kiwango cha C++14 (na kisha C++17)

Wakati fulani uliopita (katika msimu wa joto wa 2016), wakati wa uundaji wa toleo linalofuata la 1C: jukwaa la teknolojia ya Biashara, swali liliibuka ndani ya timu ya maendeleo kuhusu kusaidia kiwango kipya. C ++ 14 katika kanuni zetu. Mpito kwa kiwango kipya, kama tulivyodhani, ungeturuhusu kuandika mambo mengi kwa umaridadi zaidi, kwa urahisi na kwa uhakika, na ungerahisisha usaidizi na udumishaji wa msimbo. Na inaonekana hakuna kitu cha kushangaza katika tafsiri, ikiwa sio kwa kiwango cha msingi wa nambari na sifa maalum za nambari yetu.

Kwa wale ambao hawajui, 1C:Enterprise ni mazingira ya ukuzaji wa haraka wa maombi ya biashara ya majukwaa mtambuka na muda wa utekelezaji wa utekelezaji wao kwenye OS tofauti na DBMS. Kwa ujumla, bidhaa ina:

  • Kundi la Seva ya Programu, inaendesha kwenye Windows na Linux
  • Mteja, kufanya kazi na seva kupitia http(s) au itifaki yake ya binary, inafanya kazi kwenye Windows, Linux, macOS
  • Mteja wa wavuti, inayoendesha katika vivinjari vya Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (imeandikwa katika JavaScript)
  • Mazingira ya maendeleo (Kisanidi), inafanya kazi kwenye Windows, Linux, macOS
  • Zana za utawala seva za programu, zinaendeshwa kwenye Windows, Linux, macOS
  • Mteja wa rununu, kuunganisha kwa seva kupitia http(s), hufanya kazi kwenye vifaa vya rununu vinavyoendesha Android, iOS, Windows
  • Jukwaa la rununu β€” mfumo wa kuunda programu za simu za nje ya mtandao zenye uwezo wa kusawazisha, zinazoendeshwa kwenye Android, iOS, Windows
  • Mazingira ya maendeleo 1C: Zana za Maendeleo ya Biashara, iliyoandikwa kwa Java
  • Seva Mifumo ya Mwingiliano

Tunajaribu kuandika kanuni sawa kwa mifumo tofauti ya uendeshaji iwezekanavyo - msingi wa msimbo wa seva ni 99% ya kawaida, msingi wa msimbo wa mteja ni karibu 95%. 1C:Jukwaa la teknolojia ya Biashara limeandikwa kimsingi katika C++ na sifa za makadirio ya msimbo zimetolewa hapa chini:

  • Laini milioni 10 za nambari ya C++,
  • faili elfu 14,
  • madarasa elfu 60,
  • mbinu nusu milioni.

Na mambo haya yote yalipaswa kutafsiriwa kwa C++14. Leo tutakuambia jinsi tulivyofanya hili na kile tulichokutana nacho katika mchakato.

Jinsi tulivyotafsiri mistari milioni 10 ya msimbo wa C++ hadi kiwango cha C++14 (na kisha C++17)

Kanusho

Kila kitu kilichoandikwa hapa chini kuhusu kazi polepole/haraka, (si) utumiaji mkubwa wa kumbukumbu kwa utekelezaji wa madarasa ya kawaida katika maktaba mbalimbali inamaanisha jambo moja: hii ni kweli KWETU. Inawezekana kwamba utekelezaji wa kawaida utafaa zaidi kwa kazi zako. Tulianza kutoka kwa kazi zetu wenyewe: tulichukua data ambayo ilikuwa ya kawaida kwa wateja wetu, tukaendesha matukio ya kawaida kwao, tukaangalia utendakazi, kiasi cha kumbukumbu zinazotumiwa, n.k., na kuchanganua ikiwa sisi na wateja wetu tuliridhika na matokeo kama hayo au la. . Na walitenda kulingana na.

Tulichokuwa nacho

Hapo awali, tuliandika msimbo wa jukwaa la 1C:Enterprise 8 katika Microsoft Visual Studio. Mradi ulianza mapema miaka ya 2000 na tulikuwa na toleo la Windows-pekee. Kwa kawaida, tangu wakati huo kanuni imetengenezwa kikamilifu, taratibu nyingi zimeandikwa upya kabisa. Lakini nambari hiyo iliandikwa kulingana na kiwango cha 1998, na, kwa mfano, mabano yetu ya pembe ya kulia yalitenganishwa na nafasi ili mkusanyiko ufanikiwe, kama hii:

vector<vector<int> > IntV;

Mnamo 2006, kwa kutolewa kwa toleo la jukwaa la 8.1, tulianza kusaidia Linux na tukabadilisha maktaba ya kawaida ya watu wengine. STLPort. Moja ya sababu za mpito ilikuwa kufanya kazi na mistari mipana. Katika nambari yetu, tunatumia std::wstring, ambayo inategemea aina ya wchar_t, kote. Ukubwa wake katika Windows ni ka 2, na katika Linux chaguo-msingi ni ka 4. Hii ilisababisha kutopatana kwa itifaki zetu za binary kati ya mteja na seva, pamoja na data mbalimbali zinazoendelea. Kutumia chaguzi za gcc, unaweza kutaja kuwa saizi ya wchar_t wakati wa ujumuishaji pia ni ka 2, lakini basi unaweza kusahau kutumia maktaba ya kawaida kutoka kwa mkusanyaji, kwa sababu. hutumia glibc, ambayo kwa upande wake imeundwa kwa wchar_t 4-byte. Sababu zingine zilikuwa utekelezaji bora wa madarasa ya kawaida, usaidizi wa jedwali la hashi, na hata uigaji wa semantiki za kusonga ndani ya vyombo, ambavyo tulitumia kikamilifu. Na sababu moja zaidi, kama wanasema mwisho lakini sio mdogo, ilikuwa utendaji wa kamba. Tulikuwa na darasa letu la kamba, kwa sababu ... Kwa sababu ya maelezo mahususi ya programu yetu, utendakazi wa kamba hutumiwa sana na kwetu hii ni muhimu.

Mfuatano wetu unatokana na mawazo ya uboreshaji wa kamba yaliyotolewa mwanzoni mwa miaka ya 2000 Andrei Alexandrescu. Baadaye, Alexandrescu alipofanya kazi kwenye Facebook, kwa pendekezo lake, laini ilitumika katika injini ya Facebook ambayo ilifanya kazi kwa kanuni sawa (tazama maktaba). upumbavu).

Mstari wetu ulitumia teknolojia kuu mbili za utoshelezaji:

  1. Kwa maadili mafupi, buffer ya ndani katika kitu cha kamba yenyewe hutumiwa (haitaji mgao wa ziada wa kumbukumbu).
  2. Kwa wengine wote, mechanics hutumiwa Nakili Kwenye Andika. Thamani ya mfuatano huhifadhiwa katika sehemu moja, na kaunta ya marejeleo inatumika wakati wa ugawaji/urekebishaji.

Ili kuharakisha utungaji wa jukwaa, hatukujumuisha utekelezaji wa mtiririko kwenye lahaja yetu ya STLPort (ambayo hatukutumia), hii ilitupa mkusanyo wa haraka wa 20%. Baadaye tulilazimika kutumia kidogo Boost. Boost hutumia utiririshaji mwingi, haswa katika API zake za huduma (kwa mfano, kwa ukataji miti), kwa hivyo tulilazimika kuirekebisha ili kuondoa utumiaji wa mkondo. Hii, kwa upande wake, ilifanya iwe vigumu kwetu kuhamia matoleo mapya ya Boost.

Njia ya tatu

Wakati wa kuhamia kiwango cha C++14, tulizingatia chaguzi zifuatazo:

  1. Boresha STLPort tuliyorekebisha hadi kiwango cha C++14. Chaguo ni ngumu sana, kwa sababu ... usaidizi wa STLPort ulikomeshwa mnamo 2010, na tutalazimika kuunda nambari zake zote sisi wenyewe.
  2. Mpito hadi utekelezaji mwingine wa STL unaooana na C++14. Inapendekezwa sana kwamba utekelezaji huu uwe wa Windows na Linux.
  3. Wakati wa kukusanya kwa kila OS, tumia maktaba iliyojengwa ndani ya mkusanyaji sambamba.

Chaguo la kwanza lilikataliwa moja kwa moja kwa sababu ya kazi nyingi.

Tulifikiri juu ya chaguo la pili kwa muda fulani; kuchukuliwa kama mgombea libc++, lakini wakati huo haikufanya kazi chini ya Windows. Ili kuweka libc++ kwa Windows, itabidi ufanye kazi nyingi - kwa mfano, andika kila kitu mwenyewe kinachohusiana na nyuzi, maingiliano ya nyuzi na atomiki, kwani libc++ inatumika katika maeneo haya. API ya POSIX.

Na tulichagua njia ya tatu.

Mpito

Kwa hivyo, tulilazimika kuchukua nafasi ya utumiaji wa STLPort na maktaba za wasanifu wanaolingana (Visual Studio 2015 ya Windows, gcc 7 kwa Linux, clang 8 kwa macOS).

Kwa bahati nzuri, nambari yetu iliandikwa haswa kulingana na miongozo na haikutumia kila aina ya hila za ujanja, kwa hivyo uhamiaji wa maktaba mpya uliendelea vizuri, kwa msaada wa maandishi ambayo yalibadilisha majina ya aina, darasa, nafasi za majina na inajumuisha kwenye chanzo. mafaili. Uhamishaji huo uliathiri faili 10 za chanzo (kati ya 000). wchar_t ilibadilishwa na char14_t; tuliamua kuachana na matumizi ya wchar_t, kwa sababu char000_t huchukua baiti 16 kwenye OS zote na haiharibu uoanifu wa msimbo kati ya Windows na Linux.

Kulikuwa na matukio madogo. Kwa mfano, katika STLPort kirudisho kinaweza kutupwa kwa uhakika kwa kielekezi kwa kipengele, na katika baadhi ya maeneo katika msimbo wetu hii ilitumika. Katika maktaba mpya haikuwezekana tena kufanya hivi, na vifungu hivi vilipaswa kuchambuliwa na kuandikwa upya kwa mikono.

Kwa hiyo, uhamiaji wa msimbo umekamilika, kanuni imeundwa kwa mifumo yote ya uendeshaji. Ni wakati wa vipimo.

Uchunguzi baada ya mpito ulionyesha kushuka kwa utendaji (katika baadhi ya maeneo hadi 20-30%) na ongezeko la matumizi ya kumbukumbu (hadi 10-15%) ikilinganishwa na toleo la zamani la kanuni. Hii ilikuwa, haswa, kwa sababu ya utendakazi mdogo wa masharti ya kawaida. Kwa hivyo, tulilazimika tena kutumia laini yetu, iliyobadilishwa kidogo.

Kipengele cha kuvutia cha utekelezaji wa kontena katika maktaba zilizopachikwa pia ilifunuliwa: tupu (bila vipengele) std::map na std::seti kutoka kwa maktaba zilizojengwa hutenga kumbukumbu. Na kwa sababu ya huduma za utekelezaji, katika sehemu zingine kwenye nambari, vyombo vingi tupu vya aina hii huundwa. Vyombo vya kumbukumbu vya kawaida vimetengwa kidogo, kwa kipengele kimoja cha mizizi, lakini kwetu hii iligeuka kuwa muhimu - katika hali kadhaa, utendaji wetu ulipungua kwa kiasi kikubwa na matumizi ya kumbukumbu yameongezeka (ikilinganishwa na STLPort). Kwa hiyo, katika kanuni zetu tulibadilisha aina hizi mbili za vyombo kutoka kwa maktaba zilizojengwa na utekelezaji wao kutoka kwa Boost, ambapo vyombo hivi havikuwa na kipengele hiki, na hii ilitatua tatizo kwa kupungua na kuongezeka kwa matumizi ya kumbukumbu.

Kama inavyotokea mara nyingi baada ya mabadiliko makubwa katika miradi mikubwa, marudio ya kwanza ya msimbo wa chanzo hayakufanya kazi bila shida, na hapa, haswa, msaada wa warekebishaji wa utatuzi katika utekelezaji wa Windows ulikuja vizuri. Hatua kwa hatua tulisonga mbele, na kufikia masika ya 2017 (toleo la 8.3.11 1C:Enterprise) uhamiaji ulikamilika.

Matokeo ya

Mpito hadi kiwango cha C++14 ulituchukua takriban miezi 6. Mara nyingi, msanidi mmoja (lakini aliyehitimu sana) alifanya kazi kwenye mradi huo, na katika hatua ya mwisho wawakilishi wa timu zinazohusika na maeneo maalum walijiunga - UI, nguzo ya seva, zana za ukuzaji na usimamizi, n.k.

Mpito umerahisisha sana kazi yetu ya kuhamia matoleo mapya zaidi ya kiwango. Kwa hivyo, toleo la 1C:Enterprise 8.3.14 (linatengenezwa, toleo lililopangwa kufanyika mapema mwaka ujao) tayari limehamishiwa kwenye kiwango. C++17.

Baada ya uhamiaji, watengenezaji wana chaguo zaidi. Ikiwa hapo awali tulikuwa na toleo letu la marekebisho la STL na nafasi moja ya majina, sasa tunayo madarasa ya kawaida kutoka kwa maktaba za mkusanyaji zilizojengwa ndani ya nafasi ya majina ya stdx, kwenye nafasi ya majina ya stdx - mistari na vyombo vyetu vilivyoboreshwa kwa kazi zetu, kwa kuongeza - the toleo la hivi karibuni la kuongeza. Na msanidi hutumia madarasa hayo ambayo yanafaa kabisa kutatua shida zake.

Utekelezaji wa "asili" wa waundaji wa hoja pia husaidia katika maendeleo (wajenzi wa hoja) kwa idadi ya madarasa. Ikiwa darasa lina kijenzi cha kusonga na darasa hili limewekwa kwenye kontena, basi STL inaboresha kunakili vitu ndani ya chombo (kwa mfano, wakati chombo kinapanuliwa na inahitajika kubadilisha uwezo na kuhamisha kumbukumbu).

Kuruka kwenye marashi

Labda matokeo yasiyofurahisha zaidi (lakini sio muhimu) ya uhamiaji ni kwamba tunakabiliwa na ongezeko la sauti. faili za obj, na matokeo kamili ya kujenga na faili zote za kati ilianza kuchukua 60-70 GB. Tabia hii ni kwa sababu ya upekee wa maktaba za kisasa za kawaida, ambazo zimekuwa muhimu sana kwa ukubwa wa faili za huduma zinazozalishwa. Hii haiathiri utendakazi wa programu iliyokusanywa, lakini husababisha usumbufu kadhaa katika ukuzaji, haswa, huongeza wakati wa ujumuishaji. Mahitaji ya nafasi ya bure ya diski kwenye seva za ujenzi na kwenye mashine za wasanidi pia yanaongezeka. Watengenezaji wetu hufanya kazi kwenye matoleo kadhaa ya jukwaa sambamba, na mamia ya gigabytes ya faili za kati wakati mwingine huleta matatizo katika kazi zao. Tatizo si la kufurahisha, lakini sio muhimu; tumeahirisha suluhisho lake kwa sasa. Tunazingatia teknolojia kama moja ya chaguzi za kuisuluhisha kujenga umoja (hasa, Google hutumia wakati wa kuunda kivinjari cha Chrome).

Chanzo: mapenzi.com

Kuongeza maoni