Հիանալի հարցազրույց Cliff Click-ի հետ՝ JIT կոմպիլյացիայի հայրը Java-ում

Հիանալի հարցազրույց Cliff Click-ի հետ՝ JIT կոմպիլյացիայի հայրը Java-ումCliff Սեղմեք — Cratus-ի CTO (IoT սենսորներ գործընթացի բարելավման համար), մի քանի ստարտափների հիմնադիր և համահիմնադիր (ներառյալ Rocket Realtime School, Neurensic և H2O.ai) մի քանի հաջողված ելքերով: Քլիֆը գրել է իր առաջին կոմպիլյատորը 15 տարեկանում (Պասկալը TRS Z-80-ի համար): Նա առավել հայտնի է C2-ի վրա իր աշխատանքով Java-ում (The Sea of ​​Nodes IR): Այս կոմպիլյատորը ցույց տվեց աշխարհին, որ JIT-ը կարող է արտադրել բարձրորակ կոդ, ինչը Java-ի՝ որպես հիմնական ժամանակակից ծրագրային հարթակներից մեկի առաջացման գործոններից մեկն էր: Այնուհետև Քլիֆն օգնեց Azul Systems-ին ստեղծել 864 միջուկով հիմնական Java ծրագրային ապահովում, որն ապահովում էր GC-ի դադարները 500 գիգաբայթանոց կույտում 10 միլիվայրկյանում: Ընդհանուր առմամբ, Քլիֆին հաջողվել է աշխատել JVM-ի բոլոր ասպեկտների վրա:

 
Այս habrapost-ը հիանալի հարցազրույց է Քլիֆի հետ: Մենք կխոսենք հետևյալ թեմաների շուրջ.

  • Անցում դեպի ցածր մակարդակի օպտիմալացումներ
  • Ինչպես կատարել մեծ ռեֆակտորինգ
  • Արժեքի մոդել
  • Ցածր մակարդակի օպտիմալացման ուսուցում
  • Կատարման բարելավման գործնական օրինակներ
  • Ինչու ստեղծել ձեր սեփական ծրագրավորման լեզուն
  • Կատարողական ինժեների կարիերա
  • Տեխնիկական մարտահրավերներ
  • Մի փոքր ռեգիստրի տեղաբաշխման և բազմամիջուկների մասին
  • Կյանքի ամենամեծ մարտահրավերը

Հարցազրույցը վարում է.

  • Անդրեյ Սաթարին Amazon Web Services-ից: Իր կարիերայի ընթացքում նա հասցրել է աշխատել բոլորովին այլ նախագծերում. նա փորձարկել է NewSQL բաշխված տվյալների բազան Yandex-ում, ամպի հայտնաբերման համակարգը Kaspersky Lab-ում, բազմախաղաց խաղ Mail.ru-ում և արտարժույթի գների հաշվարկման ծառայություն Deutsche Bank-ում: Հետաքրքրված է լայնածավալ backend և բաշխված համակարգերի փորձարկումով:
  • Վլադիմիր Սիտնիկով Netcracker-ից: Տասը տարվա աշխատանք NetCracker OS-ի կատարողականության և մասշտաբայնության վրա, ծրագրակազմ, որն օգտագործվում է հեռահաղորդակցության օպերատորների կողմից ցանցի և ցանցային սարքավորումների կառավարման գործընթացները ավտոմատացնելու համար: Հետաքրքրված է Java-ի և Oracle տվյալների բազայի աշխատանքի հետ կապված խնդիրներով: Հեղինակ է ավելի քան մեկ տասնյակ կատարողականի բարելավումների պաշտոնական PostgreSQL JDBC վարորդում:

Անցում դեպի ցածր մակարդակի օպտիմալացումներ

AndrewԴուք մեծ անուն եք JIT կոմպիլյացիայի, Java-ի և ընդհանրապես կատարողական աշխատանքի աշխարհում, այնպես չէ՞: 

Ժայռ:Այդպես է։

AndrewՍկսենք կատարողական աշխատանքի վերաբերյալ մի քանի ընդհանուր հարցերից: Ի՞նչ կարծիքի եք բարձր մակարդակի և ցածր մակարդակի օպտիմալացումների միջև ընտրության մասին, ինչպիսին է CPU-ի մակարդակում աշխատելը:

ԺայռԱյո, այստեղ ամեն ինչ պարզ է: Ամենաարագ կոդը այն է, որը երբեք չի աշխատում: Ուստի միշտ պետք է սկսել բարձր մակարդակից, աշխատել ալգորիթմների վրա։ Ավելի լավ O նշումը կհաղթի ավելի վատ O նշումին, քանի դեռ բավականաչափ մեծ հաստատուններ չեն միջամտում: Ցածր մակարդակի բաները վերջինն են: Սովորաբար, եթե դուք բավականաչափ լավ եք օպտիմիզացրել ձեր մնացորդը, և դեռ որոշ հետաքրքիր բաներ են մնացել, դա ցածր մակարդակ է: Բայց ինչպե՞ս սկսել բարձր մակարդակից: Ինչպե՞ս գիտեք, որ բավականին բարձր մակարդակի աշխատանք է կատարվել: Դե... ոչ մի կերպ: Պատրաստի բաղադրատոմսեր չկան։ Դուք պետք է հասկանաք խնդիրը, որոշեք, թե ինչ եք պատրաստվում անել (որպեսզի հետագայում ավելորդ քայլեր չձեռնարկեք) և այնուհետև կարողանաք բացահայտել պրոֆիլը, որը կարող է օգտակար բան ասել։ Ինչ-որ պահի դուք ինքներդ եք հասկանում, որ ձերբազատվել եք ավելորդ բաներից, և ժամանակն է կատարել ցածր մակարդակի նուրբ թյունինգ: Սա միանշանակ արվեստի յուրահատուկ տեսակ է։ Շատ մարդիկ կան, ովքեր ավելորդ բաներ են անում, բայց այնքան արագ են շարժվում, որ ժամանակ չունեն արտադրողականության մասին անհանգստանալու։ Բայց սա այնքան ժամանակ, քանի դեռ հարց չի առաջանում. Սովորաբար 99% դեպքերում ոչ ոքի չի հետաքրքրում, թե ես ինչ եմ անում, մինչև այն պահը, երբ կրիտիկական ճանապարհին գալիս է մի կարևոր բան, որը ոչ ոքի չի հետաքրքրում: Եվ այստեղ բոլորը սկսում են բարկացնել ձեզ այն մասին, թե «ինչու այն հենց սկզբից կատարյալ չի աշխատել»: Ընդհանրապես, կատարողականում միշտ ինչ-որ բան կա բարելավելու: Բայց 99% դեպքերում դուք չունեք առաջատարներ: Դուք պարզապես փորձում եք ինչ-որ բան աշխատեցնել և այդ ընթացքում պարզել, թե ինչն է կարևոր: Դուք երբեք չեք կարող նախապես իմանալ, որ այս կտորը պետք է կատարյալ լինի, ուստի, ըստ էության, դուք պետք է կատարյալ լինեք ամեն ինչում: Բայց դա անհնար է, և դուք դա չեք անում: Միշտ շատ բաներ կան շտկելու, և դա լիովին նորմալ է:

Ինչպես կատարել մեծ ռեֆակտորինգ

Andrew- Ինչպե՞ս եք աշխատում ներկայացման վրա: Սա խաչաձեւ խնդիր է: Օրինակ, երբևէ ստիպված եղե՞լ եք աշխատել այն խնդիրների վրա, որոնք առաջանում են բազմաթիվ առկա ֆունկցիոնալության խաչմերուկից:

ԺայռԵս փորձում եմ խուսափել դրանից: Եթե ​​ես գիտեմ, որ կատարումը խնդիր կլինի, ես մտածում եմ դրա մասին նախքան կոդավորումը սկսելը, հատկապես տվյալների կառուցվածքների դեպքում: Բայց հաճախ այս ամենը բացահայտում ես շատ ավելի ուշ։ Եվ հետո դուք պետք է ծայրահեղ քայլերի դիմեք և անեք այն, ինչ ես անվանում եմ «վերագրել և նվաճել». անհրաժեշտ է բավականաչափ մեծ կտոր վերցնել: Կոդերի մի մասը դեռ պետք է վերաշարադրվի աշխատանքի հետ կապված խնդիրների կամ այլ բանի պատճառով: Ինչ էլ որ լինի կոդը վերաշարադրելու պատճառը, գրեթե միշտ ավելի լավ է վերաշարադրել ավելի մեծ կտոր, քան փոքր կտոր: Այս պահին բոլորը սկսում են վախից դողալ. «Աստված իմ, դու չես կարող այդքան կոդի դիպչել»: Բայց իրականում այս մոտեցումը գրեթե միշտ շատ ավելի լավ է աշխատում: Դուք պետք է անհապաղ ստանձնեք մեծ խնդիր, գծեք մեծ շրջանակ դրա շուրջ և ասեք. Ես կվերագրեմ ամեն ինչ շրջանակի ներսում: Եզրագիծը շատ ավելի փոքր է, քան դրա ներսում եղած բովանդակությունը, որը պետք է փոխարինվի: Եվ եթե սահմանների նման գծանշումը թույլ է տալիս կատարելապես կատարել աշխատանքը ներսում, ապա ձեր ձեռքերն ազատ են, արեք այն, ինչ ուզում եք։ Հենց որ հասկանաք խնդիրը, վերաշարադրման գործընթացը շատ ավելի հեշտ է, այնպես որ մեծ կծեք:
Միևնույն ժամանակ, երբ մեծ վերաշարադրում եք անում և հասկանում, որ կատարումը խնդիր է լինելու, կարող եք անմիջապես սկսել անհանգստանալ դրա մասին: Սա սովորաբար վերածվում է պարզ բաների, ինչպիսիք են «մի պատճենեք տվյալները, կառավարեք տվյալները հնարավորինս պարզ, փոքրացրեք դրանք»: Խոշոր վերաշարադրումների մեջ կան կատարողականը բարելավելու ստանդարտ եղանակներ: Եվ դրանք գրեթե միշտ պտտվում են տվյալների շուրջ:

Արժեքի մոդել

AndrewՓոդքասթներից մեկում դուք խոսեցիք ծախսերի մոդելների մասին՝ արտադրողականության համատեքստում: Կարո՞ղ եք բացատրել, թե ինչ նկատի ունեիք սրանով:

Ժայռ: Իհարկե: Ես ծնվել եմ մի դարաշրջանում, երբ պրոցեսորի կատարումը չափազանց կարևոր էր: Եվ այս դարաշրջանը կրկին վերադառնում է. ճակատագիրը առանց հեգնանքի չէ: Ես սկսեցի ապրել ութ բիթանոց մեքենաների ժամանակներում, իմ առաջին համակարգիչը աշխատում էր 256 բայթով: Հենց բայթերով: Ամեն ինչ շատ փոքր էր։ Հրահանգները պետք է հաշվվեին, և երբ մենք սկսեցինք բարձրանալ ծրագրավորման լեզուների փաթեթը, լեզուներն ավելի ու ավելի շատ էին դառնում: Կար Assembler-ը, հետո Basic-ը, այնուհետև C-ն, և C-ն հոգ է տարել շատ մանրամասների մասին, ինչպիսիք են ռեգիստրի տեղաբաշխումը և հրահանգների ընտրությունը: Բայց այնտեղ ամեն ինչ բավականին պարզ էր, և եթե ես ցուցիչ անեի փոփոխականի օրինակին, ապա ես կստանայի բեռնվածություն, և այս հրահանգի արժեքը հայտնի է: Սարքավորումը արտադրում է որոշակի թվով մեքենայական ցիկլեր, ուստի տարբեր բաների կատարման արագությունը կարելի է հաշվարկել՝ պարզապես գումարելով բոլոր հրահանգները, որոնք դուք պատրաստվում եք գործարկել: Յուրաքանչյուր համեմատություն/փորձարկում/մասնաճյուղ/զանգ/բեռնում/խանութ կարող է ավելացվել և ասել. դա ձեզ համար կատարման ժամանակն է: Աշխատանքի կատարման բարելավման վրա, դուք անպայման ուշադրություն կդարձնեք, թե ինչ թվեր են համապատասխանում փոքր տաք ցիկլերին: 
Բայց հենց որ անցնում ես Java-ի, Python-ի և նմանատիպ բաների, դու շատ արագ հեռանում ես ցածր մակարդակի սարքավորումներից։ Ո՞րն է Java-ում ստացող կանչելու արժեքը: Եթե ​​JIT-ը HotSpot-ում ճիշտ է գծված, այն կբեռնվի, բայց եթե դա չանի, դա կլինի ֆունկցիայի կանչ: Քանի որ զանգը թեժ օղակի վրա է, այն կվերացնի այդ օղակի մյուս բոլոր օպտիմալացումները: Հետեւաբար, իրական արժեքը շատ ավելի բարձր կլինի: Եվ դուք անմիջապես կորցնում եք կոդի մի հատվածը նայելու և հասկանալու ունակությունը, որ մենք պետք է գործարկենք այն պրոցեսորի ժամացույցի արագության, հիշողության և օգտագործվող քեշի առումով: Այս ամենը հետաքրքիր է դառնում միայն այն դեպքում, եթե դուք իսկապես մտնեք ներկայացման մեջ:
Այժմ մենք հայտնվել ենք մի իրավիճակում, երբ պրոցեսորների արագությունները գրեթե մեկ տասնամյակ չեն աճել: Հին օրերը վերադարձան! Դուք այլևս չեք կարող հույս դնել լավ մեկ թելերով կատարման վրա: Բայց եթե հանկարծ զուգահեռ հաշվարկի մեջ ես մտնում, դա աներևակայելի դժվար է, բոլորը քեզ նայում են ինչպես Ջեյմս Բոնդը: Այստեղ տասնապատիկ արագացումները սովորաբար տեղի են ունենում այն ​​վայրերում, որտեղ ինչ-որ մեկը ինչ-որ բան խառնել է: Համաժամանակյաությունը մեծ աշխատանք է պահանջում։ Այդ XNUMX անգամ արագացում ստանալու համար դուք պետք է հասկանաք ծախսերի մոդելը: Ի՞նչ և որքան արժե այն: Եվ դա անելու համար դուք պետք է հասկանաք, թե ինչպես է լեզուն տեղավորվում տակ գտնվող սարքավորման վրա:
Մարտին Թոմփսոնը հիանալի բառ է ընտրել իր բլոգի համար Մեխանիկական համակրանք! Դուք պետք է հասկանաք, թե ինչ է պատրաստվում անել ապարատը, ինչպես է դա անելու, և ինչու է առաջին հերթին անում այն, ինչ անում է: Օգտագործելով սա, բավականին հեշտ է սկսել հաշվել հրահանգները և պարզել, թե ուր է գնում կատարման ժամանակը: Եթե ​​դուք չունեք համապատասխան ուսուցում, ապա պարզապես մութ սենյակում սեւ կատու եք փնտրում: Ես տեսնում եմ, որ մարդիկ անընդհատ օպտիմիզացնում են կատարողականությունը, ովքեր պատկերացում չունեն, թե ինչ դժոխք են անում: Նրանք շատ են տառապում և առանձնապես առաջընթաց չեն գրանցում։ Եվ երբ ես վերցնում եմ նույն ծածկագիրը, մի քանի փոքր հաքեր եմ անում և ստանում հինգ կամ տասնապատիկ արագացում, նրանք նման են. Դե, դա արդար չէ, մենք արդեն գիտեինք, որ դու ավելի լավն ես: Զարմանալի. Ինչի մասին եմ խոսում... ինքնարժեքի մոդելն այն մասին է, թե ինչ կոդ եք գրում և միջինում որքան արագ է այն աշխատում մեծ պատկերում:

AndrewԵվ ինչպե՞ս կարող եք ձեր գլխում պահել այդպիսի ծավալ։ Արդյո՞ք դա ձեռք է բերվում ավելի մեծ փորձով, թե՞: Որտեղի՞ց է գալիս նման փորձը:

ԺայռԴե, ես իմ փորձը ամենահեշտ ձևով չեմ ստացել: Ես ծրագրավորել էի Ասամբլեայում դեռ այն ժամանակներում, երբ դուք կարող էիք հասկանալ յուրաքանչյուր հրահանգ: Հիմարություն է հնչում, բայց դրանից հետո Z80 հրահանգների հավաքածուն միշտ մնացել է իմ գլխում, հիշողությանս մեջ։ Խոսելուց մեկ րոպեի ընթացքում մարդկանց անունները չեմ հիշում, բայց հիշում եմ 40 տարի առաջ գրված ծածկագիրը: Ծիծաղելի է, կարծես սինդրոմ լինի»ապուշ գիտնական.

Ցածր մակարդակի օպտիմալացման ուսուցում

Andrew: Կա՞ ներս մտնելու ավելի հեշտ ճանապարհ:

Ժայռ: Այո եւ ոչ. Սարքավորումը, որը մենք բոլորս օգտագործում ենք, ժամանակի ընթացքում այնքան էլ չի փոխվել: Բոլորն օգտագործում են x86, բացառությամբ Arm սմարթֆոնների։ Եթե ​​դուք չեք անում ինչ-որ հարդքոր ներկառուցում, դուք նույնն եք անում: Լավ, հաջորդը: Հրահանգները նույնպես դարեր շարունակ չեն փոխվել։ Դուք պետք է գնաք և ինչ-որ բան գրեք ժողովում: Ոչ շատ, բայց բավական է հասկանալու համար: Դու ժպտում ես, բայց ես լրիվ լուրջ եմ խոսում։ Դուք պետք է հասկանաք լեզվի և սարքավորումների համապատասխանությունը: Դրանից հետո դուք պետք է գնաք և մի քիչ գրեք և պատրաստեք մի փոքրիկ խաղալիքի կոմպիլյատոր մի փոքրիկ խաղալիք լեզվի համար: Խաղալիքի նման նշանակում է, որ այն պետք է պատրաստվի ողջամիտ ժամկետում: Դա կարող է լինել շատ պարզ, բայց այն պետք է ստեղծի հրահանգներ: Հրահանգ ստեղծելու գործողությունը կօգնի ձեզ հասկանալ ծախսերի մոդելը կամուրջի համար, որը բոլորը գրում են բարձր մակարդակի կոդի և սարքավորման վրա աշխատող մեքենայի կոդի միջև: Այս նամակագրությունը այրվելու է ուղեղի մեջ այն պահին, երբ գրվում է կոմպիլյատորը: Նույնիսկ ամենապարզ կոմպիլյատորը: Դրանից հետո դուք կարող եք սկսել նայել Java-ին և այն փաստին, որ դրա իմաստային անդունդը շատ ավելի խորն է, և շատ ավելի դժվար է կամուրջներ կառուցել դրա վրա: Java-ում շատ ավելի դժվար է հասկանալ՝ մեր կամուրջը լավ է ստացվել, թե վատ, ինչի՞ պատճառով է այն քանդվելու, ինչը՝ ոչ։ Բայց ձեզ պետք է ինչ-որ մեկնարկային կետ, որտեղ դուք նայեք կոդը և հասկանաք. «այո, այս ստացողը պետք է ամեն անգամ գծագրվի»: Եվ հետո պարզվում է, որ երբեմն դա տեղի է ունենում, բացառությամբ այն իրավիճակի, երբ մեթոդը դառնում է չափազանց մեծ, և JIT-ը սկսում է ամեն ինչ ներդնել: Նման վայրերի կատարումը կարելի է ակնթարթորեն կանխատեսել։ Սովորաբար ստացողները լավ են աշխատում, բայց հետո նայում ես մեծ տաք օղակներին և հասկանում, որ կան որոշ գործառույթների զանգեր, որոնք լողում են այնտեղ, որոնք չգիտեն, թե ինչ են անում: Սա է ստացողների համատարած կիրառման խնդիրը, դրանց գծագրված չլինելու պատճառն այն է, որ պարզ չէ, թե դրանք ստացող են։ Եթե ​​դուք ունեք գերփոքր կոդերի բազա, կարող եք պարզապես հիշել այն և այնուհետև ասել. սա ստացող է և սա սահմանող: Կոդի մեծ բազայում յուրաքանչյուր ֆունկցիա ապրում է իր սեփական պատմությունը, որը, ընդհանուր առմամբ, ոչ մեկին հայտնի չէ։ Պրոֆիլավորողն ասում է, որ մենք կորցրել ենք ժամանակի 24%-ը ինչ-որ օղակի վրա, և հասկանալու համար, թե ինչ է անում այս օղակը, մենք պետք է նայենք յուրաքանչյուր ֆունկցիայի ներսում: Սա անհնար է հասկանալ առանց ֆունկցիան ուսումնասիրելու, և դա լրջորեն դանդաղեցնում է ըմբռնման գործընթացը։ Դրա համար ես չեմ օգտագործում գետերներ և սեթերներ, ես նոր մակարդակի եմ հասել։
Որտեղ ստանալ ծախսերի մոդելը: Դե, ինչ-որ բան կարող ես կարդալ, իհարկե... Բայց կարծում եմ, որ լավագույն միջոցը գործելն է։ Փոքր կոմպիլյատոր պատրաստելը կլինի ծախսերի մոդելը հասկանալու և այն ձեր սեփական գլխում տեղավորելու լավագույն միջոցը: Փոքր կոմպիլյատորը, որը հարմար կլինի միկրոալիքային վառարանը ծրագրավորելու համար, խնդիր է սկսնակների համար: Դե, ես նկատի ունեմ, եթե դուք արդեն ունեք ծրագրավորման հմտություններ, ապա դա պետք է բավարար լինի: Այս բոլոր բաները, ինչպիսիք են տողի վերլուծությունը, որը դուք ունեք որպես ինչ-որ հանրահաշվական արտահայտություն, այնտեղից ճիշտ հերթականությամբ մաթեմատիկական գործողությունների հրահանգներ հանելը, գրանցամատյաններից ճիշտ արժեքները վերցնելը, այս ամենը կատարվում է միանգամից: Եվ մինչ դուք դա անեք, այն կտպվի ձեր ուղեղում: Կարծում եմ, բոլորը գիտեն, թե ինչ է անում կոմպիլյատորը: Եվ դա թույլ կտա հասկանալ ծախսերի մոդելը:

Կատարման բարելավման գործնական օրինակներ

AndrewՈւրիշ ինչի՞ վրա պետք է ուշադրություն դարձնել արտադրողականության վրա աշխատելիս:

ԺայռՏվյալների կառուցվածքներ: Ի դեպ, այո, ես վաղուց չեմ դասավանդել այս դասերը... Հրթիռային դպրոց. Դա զվարճալի էր, բայց դա մեծ ջանք էր պահանջում, և ես նույնպես կյանք ունեմ: ԼԱՎ. Այսպիսով, մեծ և հետաքրքիր դասերից մեկում՝ «Ո՞ւր է գնում ձեր կատարողականը», ես ուսանողներին օրինակ բերեցի. երկուսուկես գիգաբայթ ֆինտեխ տվյալներ կարդացվեցին CSV ֆայլից, այնուհետև նրանք պետք է հաշվարկեին վաճառված ապրանքների քանակը։ . Կանոնավոր տիզ շուկայի տվյալներ: UDP փաթեթները փոխակերպվել են տեքստային ձևաչափի 70-ականներից: Chicago Merchantile Exchange - բոլոր տեսակի բաներ, ինչպիսիք են կարագը, եգիպտացորենը, սոյայի հատիկները, նման բաներ: Պետք էր հաշվել այդ ապրանքները, գործարքների քանակը, միջոցների և ապրանքների շարժի միջին ծավալը և այլն։ Սա բավականին պարզ առևտրային մաթեմատիկա է. գտեք ապրանքի կոդը (որը 1-2 նիշ է հեշ աղյուսակում), ստացեք գումարը, ավելացրեք այն առևտրային հավաքածուներից մեկին, ավելացրեք ծավալ, ավելացրեք արժեք և մի քանի այլ բաներ: Շատ պարզ մաթեմատիկա. Խաղալիքի իրականացումը շատ պարզ էր. ամեն ինչ ֆայլի մեջ է, ես կարդում եմ ֆայլը և անցնում դրա միջով՝ առանձին գրառումները բաժանելով Java տողերի, դրանցում փնտրելով անհրաժեշտ բաները և գումարելով դրանք՝ համաձայն վերը նկարագրված մաթեմատիկայի: Եվ այն աշխատում է որոշ ցածր արագությամբ:

Այս մոտեցմամբ ակնհայտ է, թե ինչ է կատարվում, և զուգահեռ հաշվարկները չեն օգնի, չէ՞: Ստացվում է, որ կատարողականի հնգապատիկ աճին կարելի է հասնել պարզապես տվյալների ճիշտ կառուցվածքների ընտրությամբ: Եվ սա զարմացնում է նույնիսկ փորձառու ծրագրավորողներին: Կոնկրետ իմ դեպքում հնարքն այն էր, որ դուք չպետք է հիշողության հատկացումներ կատարեք տաք հանգույցով: Դե, սա ամբողջ ճշմարտությունը չէ, բայց ընդհանուր առմամբ, դուք չպետք է ընդգծեք «մեկ անգամ X-ում», երբ X-ը բավականաչափ մեծ է: Երբ X-ը երկուսուկես գիգաբայթ է, պետք չէ որևէ բան հատկացնել «տառը մեկ անգամ», կամ «տողում մեկ անգամ», կամ «դաշտում մեկ անգամ», նման բան: Հենց այստեղ է ծախսվում ժամանակը։ Ինչպե՞ս է սա նույնիսկ աշխատում: Պատկերացրեք, որ ես զանգում եմ String.split() կամ BufferedReader.readLine(). Readline ստեղծում է տող մի շարք բայթերից, որոնք հայտնվել են ցանցով, յուրաքանչյուր տողի համար մեկ անգամ, հարյուր միլիոնավոր տողերից յուրաքանչյուրի համար: Ես վերցնում եմ այս տողը, վերլուծում և դեն եմ նետում: Ինչու՞ եմ այն ​​դեն նետում, լավ, ես արդեն մշակել եմ այն, այսքանը: Այսպիսով, այս 2.7G-ից կարդացված յուրաքանչյուր բայթի համար տողում գրվելու է երկու նիշ, այսինքն՝ արդեն 5.4G, և դրանք ինձ այլ բանի պետք չեն, ուստի դրանք դեն են նետվում: Եթե ​​նայեք հիշողության թողունակությանը, ապա մենք բեռնում ենք 2.7G, որը անցնում է հիշողության և հիշողության ավտոբուսի միջով պրոցեսորում, և այնուհետև կրկնակի ավելին ուղարկվում է հիշողության մեջ ընկած տողին, և այս ամենը խաթարվում է, երբ յուրաքանչյուր նոր տող ստեղծվում է: Բայց ես պետք է կարդամ այն, սարքավորումն այն կարդում է, նույնիսկ եթե ամեն ինչ ավելի ուշ փչանա: Եվ ես պետք է գրեմ այն, քանի որ ես ստեղծել եմ տող, և քեշերը լցված են. քեշը չի կարող տեղավորել 2.7G: Այսպիսով, իմ կարդացած յուրաքանչյուր բայթի համար ես կարդում եմ ևս երկու բայթ և գրում ևս երկու բայթ, և վերջում նրանք ունեն 4:1 հարաբերակցություն - այս հարաբերակցությամբ մենք վատնում ենք հիշողության թողունակությունը: Եվ հետո պարզվում է, որ եթե ես անեմ String.split() – սա վերջին անգամը չէ, որ դա անում եմ, ներսում կարող է ևս 6-7 դաշտ լինի: Այսպիսով, CSV-ն կարդալու և այնուհետև տողերը վերլուծելու դասական ծածկագիրը հանգեցնում է հիշողության թողունակության վատնման մոտ 14:1, համեմատած այն, ինչ իրականում կցանկանայիք ունենալ: Եթե ​​դեն նետեք այս ընտրանքները, կարող եք ստանալ հնգապատիկ արագացում:

Եվ դա այնքան էլ դժվար չէ: Եթե ​​դուք նայեք ծածկագրին ճիշտ տեսանկյունից, ապա ամեն ինչ բավականին պարզ է դառնում, երբ հասկանում եք խնդիրը: Պետք չէ ընդհանրապես դադարել տեղաբաշխել հիշողությունը. միակ խնդիրն այն է, որ դուք ինչ-որ բան հատկացնում եք, և այն անմիջապես մեռնում է, և ճանապարհին այն այրում է կարևոր ռեսուրս, որն այս դեպքում հիշողության թողունակությունն է: Եվ այս ամենը հանգեցնում է արտադրողականության անկման: x86-ում սովորաբար անհրաժեշտ է ակտիվորեն այրել պրոցեսորային ցիկլերը, բայց այստեղ դուք շատ ավելի վաղ այրել եք ամբողջ հիշողությունը: Լուծումը լիցքաթափման քանակի կրճատումն է: 
Խնդրի մյուս մասն այն է, որ եթե դուք գործարկում եք պրոֆիլավորիչը, երբ հիշողության շերտը վերջանում է, հենց այն ժամանակ, երբ դա տեղի է ունենում, դուք սովորաբար սպասում եք, որ քեշը վերադառնա, քանի որ այն լի է աղբով, որը դուք հենց նոր արտադրել եք, այդ բոլոր տողերը: Հետևաբար, յուրաքանչյուր բեռնման կամ պահեստավորման գործողություն դառնում է դանդաղ, քանի որ դրանք հանգեցնում են քեշի բացթողումների. Հետևաբար, պրոֆիլավորողը պարզապես ցույց կտա տաք պատահական աղմուկը, որը քսվում է ամբողջ օղակի ընթացքում. կոդում առանձին տաք հրահանգ կամ տեղ չի լինի: Միայն աղմուկ. Եվ եթե նայեք GC ցիկլերին, ապա դրանք բոլորը երիտասարդ սերնդի են և գերարագ՝ միկրովայրկյան կամ առավելագույնը միլիվայրկյան: Չէ՞ որ այս ամբողջ հիշողությունն ակնթարթորեն մեռնում է։ Դուք միլիարդավոր գիգաբայթներ եք հատկացնում, իսկ նա կտրում է դրանք, կտրում և նորից կտրում: Այս ամենը տեղի է ունենում շատ արագ։ Ստացվում է, որ կան էժան GC ցիկլեր, ջերմ աղմուկ ամբողջ ցիկլի ընթացքում, բայց մենք ուզում ենք ստանալ 5x արագացում: Այս պահին ձեր գլխում ինչ-որ բան պետք է փակվի և հնչի. «Ինչո՞ւ է սա»: Հիշողության շերտի արտահոսքը չի ցուցադրվում դասական վրիպազերծիչում, դուք պետք է գործարկեք ապարատային աշխատանքի հաշվիչի վրիպազերծիչը և տեսնեք այն ինքներդ և ուղղակիորեն: Բայց սա ուղղակիորեն չի կարելի կասկածել այս երեք ախտանիշներից։ Երրորդ ախտանիշն այն է, երբ նայում եք, թե ինչ եք կարևորում, հարցնում եք պրոֆիլատիրոջը, և նա պատասխանում է. Հենց դա տեղի ունենա, դուք հասկանում եք, որ ստեղծել եք չափազանց շատ առարկաներ և այրել եք հիշողության ողջ գիծը: Սա պարզելու միջոց կա, բայց դա ակնհայտ չէ։ 

Խնդիրը տվյալների կառուցվածքում է. մերկ կառուցվածքը, որի հիմքում ընկած է այն ամենը, ինչ տեղի է ունենում, այն չափազանց մեծ է, այն սկավառակի վրա 2.7 Գ է, ուստի այս բանի կրկնօրինակումը շատ անցանկալի է. դուք ցանկանում եք անմիջապես բեռնել այն ցանցի բայթ բուֆերից: գրանցամատյանների մեջ, որպեսզի հինգ անգամ չկարդաց-գրեն տողը ետ ու առաջ: Ցավոք սրտի, Java-ն լռելյայն չի տալիս ձեզ նման գրադարան՝ որպես JDK-ի մաս: Բայց սա չնչին է, չէ՞: Ըստ էության, սրանք կոդի 5-10 տող են, որոնք կօգտագործվեն ձեր սեփական բուֆերային լարային բեռնիչն իրականացնելու համար, որը կրկնում է տողերի դասի վարքագիծը՝ միաժամանակ լինելով հիմքում ընկած բայթ բուֆերի շուրջը: Արդյունքում ստացվում է, որ դուք աշխատում եք գրեթե այնպես, ասես տողերի հետ, բայց իրականում բուֆերի ցուցիչները շարժվում են այնտեղ, և չմշակված բայթերը ոչ մի տեղ չեն պատճենվում, և այդպիսով նույն բուֆերները կրկին ու կրկին օգտագործվում են, և օպերացիոն համակարգը ուրախ է ձեզ վրա վերցնել այն բաները, որոնց համար նախատեսված է, օրինակ՝ այս բայթային բուֆերների թաքնված կրկնակի բուֆերացումը, և դուք այլևս չեք մանրացնում անհարկի տվյալների անվերջ հոսքը: Ի դեպ, հասկանու՞մ եք, որ GC-ով աշխատելիս երաշխավորված է, որ յուրաքանչյուր հիշողության հատկացում չի երևա պրոցեսորին վերջին GC ցիկլից հետո: Հետևաբար, այս ամենը չի կարող լինել քեշում, և այնուհետև տեղի է ունենում 100% երաշխավորված բացթողում: Սլաքի հետ աշխատելիս x86-ում ռեգիստրը հիշողությունից հանելը տևում է 1-2 ժամացույցի ցիկլ, և հենց դա տեղի ունենա, դուք վճարում եք, վճարում եք, վճարում եք, քանի որ հիշողությունը միացված է: ինը պահոց – և սա հիշողության բաշխման արժեքն է: Իրական արժեք.

Այլ կերպ ասած, տվյալների կառուցվածքները փոխելու ամենադժվար բանն է: Եվ երբ հասկանում եք, որ ընտրել եք տվյալների սխալ կառուցվածքը, որը հետագայում կսպանի կատարողականը, սովորաբար շատ աշխատանք կա անելու, բայց եթե դա չանեք, ամեն ինչ կվատթարանա: Նախևառաջ պետք է մտածել տվյալների կառուցվածքների մասին, սա կարևոր է: Հիմնական ծախսերն այստեղ ընկնում են ճարպային տվյալների կառուցվածքների վրա, որոնք սկսում են օգտագործվել «Ես պատճենեցի տվյալների կառուցվածքը X-ը տվյալների Y կառուցվածքի մեջ, քանի որ ինձ ավելի լավ է դուր գալիս Y-ի ձևը»: Բայց պատճենահանման գործողությունը (որը էժան է թվում) իրականում վատնում է հիշողության թողունակությունը, և հենց այստեղ է թաղվում կատարման ամբողջ վատնված ժամանակը: Եթե ​​ես ունեմ JSON-ի հսկա տող, և ես ուզում եմ այն ​​վերածել POJO-ների կառուցվածքային DOM ծառի կամ որևէ այլ բանի, ապա այդ տողը վերլուծելու և POJO-ի կառուցումը, իսկ հետո նորից POJO մուտք գործելու գործողությունը կհանգեցնի անհարկի ծախսերի. ոչ էժան. Բացառությամբ, եթե դուք վազում եք POJO-ների շուրջը շատ ավելի հաճախ, քան վազում եք պարանի շուրջը: Անշուշտ, դուք կարող եք փոխարենը փորձել գաղտնազերծել տողը և այնտեղից հանել միայն այն, ինչ ձեզ հարկավոր է՝ առանց այն որևէ POJO-ի վերածելու: Եթե ​​այս ամենը տեղի է ունենում մի ճանապարհով, որտեղից առավելագույն կատարում է պահանջվում, ձեզ համար ոչ մի POJO, դուք պետք է ինչ-որ կերպ ուղղակիորեն փորփրեք գիծը:

Ինչու ստեղծել ձեր սեփական ծրագրավորման լեզուն

AndrewԴուք ասացիք, որ ծախսերի մոդելը հասկանալու համար պետք է գրել ձեր սեփական փոքրիկ լեզուն...

ԺայռՈչ թե լեզու, այլ կոմպիլյատոր։ Լեզուն և կոմպիլյատորը երկու տարբեր բաներ են: Ամենակարևոր տարբերությունը քո գլխում է։ 

AndrewԻ դեպ, որքան գիտեմ, դուք փորձարկումներ եք անում՝ ստեղծելով ձեր սեփական լեզուներ։ Ինչի համար?

Ժայռ: Որովհետև ես կարող եմ: Ես կիսաթոշակառու եմ, ուստի սա իմ հոբբին է: Ես իմ ամբողջ կյանքում կիրառել եմ ուրիշների լեզուները: Ես նաև շատ եմ աշխատել իմ կոդավորման ոճի վրա։ Եվ նաև այն պատճառով, որ ես խնդիրներ եմ տեսնում այլ լեզուներով: Ես տեսնում եմ, որ ծանոթ բաներ անելու ավելի լավ եղանակներ կան։ Եվ ես կօգտագործեի դրանք: Ես պարզապես հոգնել եմ իմ մեջ, Java-ում, Python-ում, ցանկացած այլ լեզվով խնդիրներ տեսնելուց: Այժմ ես գրում եմ React Native-ում, JavaScript-ում և Elm-ում որպես հոբբի, որը ոչ թե թոշակի անցնելու, այլ ակտիվ աշխատանքի մասին է: Ես գրում եմ նաև Python-ով և, ամենայն հավանականությամբ, կշարունակեմ աշխատել Java backend-ների մեքենայական ուսուցման վրա: Կան բազմաթիվ հանրաճանաչ լեզուներ, և դրանք բոլորն ունեն հետաքրքիր առանձնահատկություններ: Յուրաքանչյուր ոք լավն է յուրովի, և դուք կարող եք փորձել ի մի բերել այս բոլոր հատկանիշները: Այսպիսով, ես ուսումնասիրում եմ ինձ հետաքրքրող բաները, լեզվի վարքագիծը, փորձում եմ խելամիտ իմաստաբանություն գտնել: Եվ մինչ այժմ ես հաջողության եմ հասնում: Այս պահին ես պայքարում եմ հիշողության իմաստաբանության հետ, քանի որ ուզում եմ ունենալ այն, ինչպես C-ում և Java-ում, և ստանալ հզոր հիշողության մոդել և հիշողության իմաստաբանություն բեռների և պահեստների համար: Միևնույն ժամանակ ունեցեք ավտոմատ տիպի եզրակացություն, ինչպես Haskell-ում: Այստեղ ես փորձում եմ խառնել Haskell-ի նման տիպի եզրակացությունը հիշողության աշխատանքի հետ և՛ C-ում, և՛ Java-ում: Սա այն է, ինչ ես անում եմ օրինակ վերջին 2-3 ամիսների ընթացքում։

AndrewԵթե ​​դուք կառուցեք լեզու, որն ավելի լավ կողմեր ​​է վերցնում այլ լեզուներից, կարծում եք, որ ինչ-որ մեկը կանի հակառակը. վերցնել ձեր գաղափարները և օգտագործել դրանք:

ԺայռՀենց այսպես են հայտնվում նոր լեզուներ: Ինչու է Java-ն նման C-ին: Քանի որ C-ն ուներ լավ շարահյուսություն, որը բոլորը հասկանում էին, և Java-ն ոգեշնչված էր այս շարահյուսությունից՝ ավելացնելով տիպի անվտանգություն, զանգվածի սահմանների ստուգում, GC, և նրանք նաև բարելավեցին որոշ բաներ C-ից: Նրանք ավելացրեցին իրենցը: Բայց նրանք բավականին շատ էին ոգեշնչվել, չէ՞: Բոլորը կանգնած են քեզնից առաջ եկած հսկաների ուսերին,- ահա թե ինչպես է առաջընթացը:

AndrewԻնչպես հասկացա, ձեր լեզուն ապահով կլինի հիշողության մեջ: Մտածե՞լ եք Rust-ից փոխառության ստուգիչի նման բան իրականացնելու մասին: Դուք նայե՞լ եք նրան, ի՞նչ եք մտածում նրա մասին։

ԺայռԴե, ես տարիներ շարունակ գրում եմ C-ն՝ այս ամբողջ մալլոկով և անվճար, և ձեռքով կառավարում եմ կյանքի տևողությունը: Գիտեք, ձեռքով կառավարվող կյանքի ժամանակի 90-95%-ը նույն կառուցվածքն ունի: Եվ դա շատ, շատ ցավալի է ձեռքով անել: Կցանկանայի, որ կոմպիլյատորը պարզապես պատմեր, թե ինչ է կատարվում այնտեղ և ինչի եք հասել ձեր գործողություններով։ Որոշ բաների համար, պարտքի ստուգիչը դա անում է առանց տուփի: Եվ այն պետք է ավտոմատ կերպով ցուցադրի տեղեկատվություն, հասկանա ամեն ինչ և նույնիսկ չծանրաբեռնի ինձ այս հասկացողությունը ներկայացնելով։ Այն պետք է կատարի առնվազն տեղային փախուստի վերլուծություն, և միայն այն դեպքում, եթե այն ձախողվի, ապա պետք է ավելացնել տիպի ծանոթագրություններ, որոնք կբնութագրեն կյանքի տևողությունը, և նման սխեման շատ ավելի բարդ է, քան փոխառության ստուգիչը կամ իսկապես գոյություն ունեցող հիշողության ստուգիչը: «Ամեն ինչ լավ է» և «Ես ոչինչ չեմ հասկանում» ընտրությունը՝ ոչ, պետք է ավելի լավ բան լինի: 
Այսպիսով, որպես մեկը, ով գրել է շատ կոդ C-ով, ես կարծում եմ, որ ամենակարևորը ավտոմատ կյանքի կառավարման համար աջակցություն ունենալն է: Ես նաև հոգնել եմ Java-ի հիշողությունից, և հիմնական բողոքը GC-ն է: Երբ դուք հիշողություն եք հատկացնում Java-ում, դուք չեք վերադարձնի այն հիշողությունը, որը տեղական էր վերջին GC ցիկլում: Հիշողության ավելի ճշգրիտ կառավարում ունեցող լեզուներում դա այդպես չէ: Եթե ​​դուք զանգահարեք malloc, դուք անմիջապես ստանում եք այն հիշողությունը, որը սովորաբար պարզապես օգտագործվում էր: Սովորաբար դուք ինչ-որ ժամանակավոր բաներ եք անում հիշողությամբ և անմիջապես հետ եք վերադարձնում այն։ Եվ այն անմիջապես վերադառնում է մալլոկի լողավազան, և հաջորդ malloc ցիկլը նորից դուրս է հանում այն: Հետևաբար, հիշողության իրական օգտագործումը կրճատվում է մինչև տվյալ պահին կենդանի օբյեկտների հավաքածուն, գումարած արտահոսքերը: Եվ եթե ամեն ինչ բացարձակապես անպարկեշտ կերպով չի արտահոսում, հիշողության մեծ մասը հայտնվում է քեշերում և պրոցեսորում, և այն արագ է աշխատում: Բայց պահանջում է շատ ձեռքով հիշողության կառավարում malloc-ով և անվճար, որը կոչվում է ճիշտ կարգով, ճիշտ տեղում: Rust-ը կարող է ինքնուրույն կարգավորել դա, և շատ դեպքերում տալիս է նույնիսկ ավելի լավ կատարում, քանի որ հիշողության սպառումը կրճատվում է մինչև ընթացիկ հաշվարկը, ի տարբերություն հիշողությունը ազատելու հաջորդ GC ցիկլին սպասելու: Արդյունքում մենք ստացանք արդյունավետությունը բարելավելու շատ հետաքրքիր միջոց: Եվ բավականին հզոր, նկատի ունեմ, որ ես նման բաներ էի անում ֆինտեխի համար տվյալները մշակելիս, և դա ինձ թույլ տվեց մոտ հինգ անգամ արագություն ստանալ: Դա բավականին մեծ խթան է, հատկապես մի աշխարհում, որտեղ պրոցեսորները չեն արագանում, և մենք դեռ սպասում ենք բարելավումների:

Կատարողական ինժեների կարիերա

AndrewԵս կցանկանայի նաև հարցնել առհասարակ կարիերայի մասին: Դուք հայտնի դարձաք ձեր JIT աշխատանքով HotSpot-ում, այնուհետև տեղափոխվեցիք Azul, որը նույնպես JVM ընկերություն է: Բայց մենք արդեն ավելի շատ աշխատում էինք ապարատային, քան ծրագրային ապահովման վրա: Եվ հետո նրանք հանկարծ անցան Big Data-ի և Machine Learning-ի, իսկ հետո խարդախության հայտնաբերման: Ինչպե՞ս դա տեղի ունեցավ: Սրանք զարգացման շատ տարբեր ոլորտներ են:

ԺայռԵս բավականին երկար ժամանակ զբաղվում եմ ծրագրավորմամբ և հասցրել եմ շատ տարբեր դասերի մասնակցել: Եվ երբ մարդիկ ասում են. «օ, դու ես, ով JIT արեց Java-ի համար», միշտ ծիծաղելի է: Բայց մինչ այդ ես աշխատում էի PostScript-ի կլոնի վրա՝ այն լեզուն, որը Apple-ը ժամանակին օգտագործում էր իր լազերային տպիչների համար: Իսկ մինչ այդ ես արել եմ չորրորդ լեզվի իրականացում։ Կարծում եմ, որ ինձ համար ընդհանուր թեման գործիքների մշակումն է: Ամբողջ կյանքում ես գործիքներ եմ պատրաստում, որոնցով ուրիշ մարդիկ գրում են իրենց թույն ծրագրերը։ Բայց ես նաև ներգրավված էի օպերացիոն համակարգերի, դրայվերների, միջուկի մակարդակի կարգաբերիչների, ՕՀ-ի մշակման լեզուների մշակմամբ, որոնք սկսվեցին չնչին, բայց ժամանակի ընթացքում ավելի ու ավելի բարդացան: Բայց հիմնական թեման դեռ գործիքների մշակումն է։ Իմ կյանքի մի մեծ մասն անցել է Azul-ի և Sun-ի միջև, և դա վերաբերում էր Java-ին: Բայց երբ ես մտա Մեծ տվյալների և մեքենայական ուսուցման մեջ, ես նորից դրեցի իմ շքեղ գլխարկը և ասացի. «Ահ, հիմա մենք ունենք ոչ աննշան խնդիր, և շատ հետաքրքիր բաներ են կատարվում, և մարդիկ ինչ-որ բաներ են անում»: Սա զարգացման հիանալի ուղի է:

Այո, ես իսկապես սիրում եմ բաշխված հաշվարկը: Իմ առաջին աշխատանքը եղել է որպես ուսանող C-ում, գովազդային նախագծի վրա: Սա բաշխվել է Zilog Z80 չիպերի վրա հաշվարկելով, որոնք տվյալներ են հավաքում իրական անալոգային անալիզատորի կողմից արտադրված անալոգային OCR-ի համար: Թույն ու լրիվ խենթ թեմա էր։ Բայց խնդիրներ կային, որոշ հատված ճիշտ չէր ճանաչվել, ուստի պետք էր նկար հանել և ցույց տալ այն մարդուն, ով արդեն կարող էր կարդալ իր աչքերով և հայտնել, թե ինչ է ասվում, և հետևաբար կային աշխատատեղեր տվյալների հետ, և այս աշխատանքները: ունեին իրենց լեզուն: Կար մի backend, որը մշակում էր այս ամենը. Z80-ները աշխատում էին vt100 տերմինալների հետ զուգահեռ՝ մեկ անձի համար, իսկ Z80-ի վրա կար զուգահեռ ծրագրավորման մոդել: Հիշողության որոշ ընդհանուր կտոր, որը կիսում են բոլոր Z80-ները աստղային կոնֆիգուրացիայի մեջ; Հետևի ինքնաթիռը նույնպես համօգտագործվում էր, և RAM-ի կեսը համօգտագործվում էր ցանցի ներսում, իսկ մյուս կեսը մասնավոր էր կամ գնաց ուրիշ բանի: Զուգահեռաբար բաշխված իմաստալից բարդ համակարգ՝ ընդհանուր... կիսամյակային հիշողությամբ: Ե՞րբ էր սա… Ես նույնիսկ չեմ կարող հիշել, ինչ-որ տեղ 80-ականների կեսերին: Բավականին վաղուց։ 
Այո, ենթադրենք, որ 30 տարին բավականին երկար ժամանակ է: Բաշխված հաշվարկների հետ կապված խնդիրներ կան բավականին երկար ժամանակ, մարդիկ վաղուց պատերազմում են դրա դեմ: Beowulf- կլաստերներ. Նման կլաստերները նման են... Օրինակ՝ կա Ethernet և ձեր արագ x86-ը միացված է այս Ethernet-ին, և հիմա դուք ցանկանում եք ստանալ կեղծ համօգտագործվող հիշողություն, քանի որ ոչ ոք այն ժամանակ չէր կարող բաշխված հաշվողական կոդավորում անել, դա չափազանց դժվար էր և հետևաբար այնտեղ կեղծ համօգտագործվող հիշողություն էր x86-ի պաշտպանական հիշողության էջերով, և եթե դուք գրել եք այս էջին, ապա մենք մյուս պրոցեսորներին ասացինք, որ եթե նրանք մուտք ունենան նույն ընդհանուր հիշողությունը, այն պետք է բեռնվի ձեզանից, և, հետևաբար, մի պրոտոկոլի պես մի բան աջակցելու համար: հայտնվեց քեշի համահունչությունը և դրա համար նախատեսված ծրագրակազմը: Հետաքրքիր հայեցակարգ. Իրական խնդիրը, իհարկե, այլ բան էր։ Այս ամենն աշխատեց, բայց դուք արագ կատարման հետ կապված խնդիրներ ունեցաք, քանի որ ոչ ոք չէր հասկանում կատարման մոդելները բավական լավ մակարդակով. հիշողության հասանելիության ինչպիսի օրինաչափություններ կային, ինչպես համոզվել, որ հանգույցներն անվերջ չեն պինգում միմյանց և այլն:

Այն, ինչ ես հայտնեցի H2O-ում, այն է, որ հենց մշակողները պատասխանատու են որոշելու, թե որտեղ է թաքնված զուգահեռությունը և որտեղ՝ ոչ: Ես ստեղծեցի կոդավորման մոդել, որը հեշտ ու պարզ դարձրեց բարձր արդյունավետության կոդ գրելը: Բայց դանդաղ աշխատող կոդ գրելը դժվար է, վատ տեսք կունենա։ Պետք է լրջորեն փորձել դանդաղ կոդ գրել, ստիպված կլինեք օգտագործել ոչ ստանդարտ մեթոդներ։ Արգելակման կոդը տեսանելի է առաջին հայացքից։ Արդյունքում, դուք սովորաբար գրում եք կոդ, որն արագ է աշխատում, բայց դուք պետք է հասկանաք, թե ինչ անել ընդհանուր հիշողության դեպքում: Այս ամենը կապված է մեծ զանգվածների հետ, և այնտեղ պահվածքը նման է զուգահեռ Java-ի ոչ անկայուն մեծ զանգվածներին: Նկատի ունեմ, պատկերացրեք, որ երկու շարանը գրում է զուգահեռ զանգվածի վրա, որոնցից մեկը հաղթում է, իսկ մյուսը, համապատասխանաբար, պարտվում է, և դուք չգիտեք, թե որն է: Եթե ​​դրանք անկայուն չեն, ապա կարգը կարող է լինել այն, ինչ ուզում եք, և սա իսկապես լավ է աշխատում: Մարդիկ իսկապես հոգ են տանում գործողությունների կարգի մասին, նրանք դնում են ցնդող նյութերը ճիշտ տեղերում և ակնկալում են հիշողության հետ կապված կատարողական խնդիրներ ճիշտ տեղերում: Հակառակ դեպքում, նրանք պարզապես կգրեին կոդը 1-ից N օղակների տեսքով, որտեղ N-ը մի քանի տրիլիոն է, այն հույսով, որ բոլոր բարդ դեպքերն ինքնաբերաբար կդառնան զուգահեռ, և այն չի աշխատում այնտեղ: Բայց H2O-ում սա ոչ Java է, ոչ էլ Scala, եթե ցանկանում եք, կարող եք այն համարել «Java մինուս մինուս»: Սա շատ հստակ ծրագրավորման ոճ է և նման է պարզ C կամ Java կոդ գրելուն օղակներով և զանգվածներով: Բայց միևնույն ժամանակ հիշողությունը կարող է մշակվել տերաբայթով: Ես դեռ օգտագործում եմ H2O: Ես ժամանակ առ ժամանակ օգտագործում եմ այն ​​տարբեր նախագծերում, և դա դեռ ամենաարագ բանն է, տասնյակ անգամ ավելի արագ, քան իր մրցակիցները: Եթե ​​դուք կատարում եք Big Data սյունակային տվյալների հետ, ապա շատ դժվար է հաղթել H2O-ին:

Տեխնիկական մարտահրավերներ

AndrewՈ՞րն է եղել Ձեր ամենամեծ մարտահրավերը Ձեր ողջ կարիերայի ընթացքում:

ԺայռՀարցի տեխնիկական, թե ոչ տեխնիկական մասի՞ն ենք քննարկում։ Ես կասեի, որ ամենամեծ մարտահրավերները տեխնիկական խնդիրները չեն: 
Ինչ վերաբերում է տեխնիկական մարտահրավերներին. Ես պարզապես հաղթեցի նրանց։ Ես նույնիսկ չգիտեմ, թե որն էր ամենամեծը, բայց կային բավականին հետաքրքիրներ, որոնք բավականին ժամանակ խլեցին, մտավոր պայքար: Երբ գնացի Sun, համոզված էի, որ արագ կոմպիլյատոր եմ պատրաստելու, ու մի խումբ ավագներ ի պատասխան ասում էին, որ երբեք չեմ հաջողի։ Բայց ես գնացի այս ճանապարհով, գրեցի մի կոմպիլյատոր ռեգիստրի հատկացնողին, և դա բավականին արագ էր: Այն նույնքան արագ էր, որքան ժամանակակից C1-ը, բայց այն ժամանակ հատկացնողը շատ ավելի դանդաղ էր գործում, և հետադարձ հայացքից դա տվյալների կառուցվածքի մեծ խնդիր էր: Ինձ դա անհրաժեշտ էր գրաֆիկական ռեգիստրի հատկացուցիչ գրելու համար և ես չհասկացա կոդերի արտահայտչականության և արագության երկընտրանքը, որը կար այդ դարաշրջանում և շատ կարևոր էր։ Պարզվեց, որ տվյալների կառուցվածքը սովորաբար գերազանցում է այն ժամանակվա x86-ների քեշի չափը, և, հետևաբար, եթե ես ի սկզբանե ենթադրում էի, որ ռեգիստրի հատկացուցիչը կաշխատի ընդհանուր jitter ժամանակի 5-10 տոկոսը, ապա իրականում պարզվեց. 50 տոկոս։

Ժամանակի ընթացքում կոմպիլյատորը դարձավ ավելի մաքուր և արդյունավետ, ավելի շատ դեպքերում դադարեց սարսափելի կոդ ստեղծելուց, և կատարողականությունը սկսեց ավելի ու ավելի նմանվել C կոմպիլյատորի արտադրածին: Եթե, իհարկե, չգրեք ինչ-որ անհեթեթություն, որը նույնիսկ C-ն չի արագացնում: . Եթե ​​C-ի նման կոդ գրեք, ավելի շատ դեպքերում կստանաք C-ի նման կատարում: Եվ որքան առաջ էիր գնում, այնքան ավելի հաճախ էիր ստանում կոդ, որն ասիմպտոտիկորեն համընկնում էր C մակարդակի հետ, ռեգիստրի հատկացուցիչը սկսում էր ամբողջական տեսք ունենալ... անկախ նրանից՝ քո կոդը արագ է աշխատում, թե դանդաղ: Ես շարունակեցի աշխատել հատկացնողի վրա, որպեսզի այն ավելի լավ ընտրություն կատարի: Նա դառնում էր ավելի ու ավելի դանդաղ, բայց նա ավելի ու ավելի լավ կատարում էր այն դեպքերում, երբ ոչ ոք չէր կարող հաղթահարել: Ես կարող էի սուզվել ռեգիստրի բաշխիչի մեջ, թաղել այնտեղ մեկ ամսվա աշխատանք, և հանկարծ ամբողջ կոդը կսկսի գործել 5% ավելի արագ: Դա տեղի էր ունենում ժամանակ առ ժամանակ, և ռեգիստրի հատկացուցիչը դառնում էր արվեստի գործ. բոլորը սիրում էին կամ ատում այն, իսկ ակադեմիայի մարդիկ հարցեր էին տալիս «ինչու է ամեն ինչ այսպես արվում» թեմայով, ինչու ոչ: գծի սկանավորում, և որն է տարբերությունը: Պատասխանը դեռ նույնն է. գրաֆիկի գունավորման վրա հիմնված հատկացուցիչը և բուֆերային կոդի հետ շատ զգույշ աշխատանքը հավասար է հաղթանակի զենքի, լավագույն համադրությանը, որը ոչ ոք չի կարող հաղթել: Եվ սա բավականին ոչ ակնհայտ բան է։ Մնացած ամեն ինչ, որ այնտեղ անում է կազմողը, բավականին լավ ուսումնասիրված բաներ են, թեև դրանք նույնպես հասցվել են արվեստի մակարդակի։ Ես միշտ անում էի այնպիսի բաներ, որոնք պետք է կազմողին վերածեին արվեստի գործի։ Բայց սրանից ոչ մեկը արտառոց բան չէր, բացի ռեգիստրի հատկացնողից: Խաբեությունը զգույշ լինելն է կրճատել ծանրաբեռնվածության տակ և, եթե դա տեղի ունենա (կարող եմ ավելի մանրամասն բացատրել, եթե հետաքրքրված եք), դա նշանակում է, որ դուք կարող եք ավելի ագրեսիվ կերպով ներդնել՝ առանց կատարողականի ժամանակացույցում անկման վտանգի: Այդ օրերին կային մի փունջ լայնածավալ կոմպիլյատորներ, որոնք կախված էին բլիթներով և սուլիչներով, որոնք ունեին գրանցամատյաններ, բայց ոչ ոք չէր կարող դա անել:

Խնդիրն այն է, որ եթե ավելացնեք մեթոդներ, որոնք ենթակա են ներգծման, ավելացման և ներկառուցման տարածքի ավելացման, օգտագործված արժեքների հավաքածուն ակնթարթորեն գերազանցում է ռեգիստրների թիվը, և դուք պետք է կտրեք դրանք: Կրիտիկական մակարդակը սովորաբար գալիս է այն ժամանակ, երբ հատկացնողը հանձնվում է, և արտահոսքի մեկ լավ թեկնածուն արժե մյուսը, դուք կվաճառեք ընդհանուր առմամբ վայրի իրեր: Այստեղ ներդնելու արժեքն այն է, որ դուք կորցնում եք գլխավճարի մի մասը, զանգելու և խնայելու համար, դուք կարող եք տեսնել արժեքները ներսում և կարող եք հետագայում օպտիմալացնել դրանք: Ներգրավման արժեքն այն է, որ ձևավորվում են մեծ թվով կենդանի արժեքներ, և եթե ձեր ռեգիստրի հատկացուցիչը այրվում է ավելին, քան անհրաժեշտ է, դուք անմիջապես կորցնում եք: Հետևաբար, տեղաբաշխողների մեծամասնությունը խնդիր ունի. երբ ներդիրը հատում է որոշակի գիծ, ​​աշխարհում ամեն ինչ սկսում է կրճատվել, և արտադրողականությունը կարող է լցվել զուգարանից: Նրանք, ովքեր իրականացնում են կոմպիլյատորը, ավելացնում են որոշ էվրիստիկա. օրինակ՝ դադարեցնել ներդիրումը՝ սկսելով բավականին մեծ չափսերից, քանի որ հատկացումները կփչացնեն ամեն ինչ: Ահա թե ինչպես է ձևավորվում կատարողականի գրաֆիկի շեղում. դու ներդիր, ներդիր, կատարումը կամաց-կամաց աճում է, և հետո բում: – այն ցած է ընկնում արագ ժեկի պես, որովհետև դու շատ ես շարել: Ահա թե ինչպես էր ամեն ինչ աշխատում մինչև Java-ի գալուստը։ Java-ն պահանջում է շատ ավելի ներդիրում, ուստի ես ստիպված էի իմ հատկացուցիչը դարձնել շատ ավելի ագրեսիվ, որպեսզի այն հարթվի, այլ ոչ թե խափանվի, և եթե շատ եք ներդնում, այն սկսում է թափվել, բայց հետո «այլևս չթափվելու» պահը դեռ գալիս է: Հետաքրքիր դիտարկում է, և այն ինձ մոտ ուղղակի տեղից եկավ, ոչ ակնհայտ, բայց լավ արդյունք տվեց։ Ես սկսեցի ագրեսիվ ներդիրում, և դա ինձ տարավ այնպիսի վայրեր, որտեղ Java-ն ու C-ն աշխատում են կողք կողքի: Նրանք իսկապես մոտ են. ես կարող եմ գրել Java կոդ, որը զգալիորեն ավելի արագ է, քան C կոդը և նման բաներ, բայց միջին հաշվով, իրերի մեծ պատկերում, դրանք մոտավորապես համեմատելի են: Կարծում եմ, որ այս արժանիքների մի մասը գրանցամատյան հատկացնողն է, որն ինձ թույլ է տալիս հնարավորինս հիմար կերպով ներդնել: Ես ուղղակի գծում եմ այն ​​ամենը, ինչ տեսնում եմ: Այստեղ հարցն այն է, թե արդյոք բաշխիչը լավ է աշխատում, արդյոք արդյունքը խելացիորեն աշխատող կոդ է: Սա մեծ մարտահրավեր էր՝ հասկանալ այս ամենը և գործի դնել:

Մի փոքր ռեգիստրի տեղաբաշխման և բազմամիջուկների մասին

ՎլադիմիրՌեգիստրների տեղաբաշխման նման խնդիրները կարծես հավերժական, անվերջանալի թեմա լինեն: Հետաքրքիր է, երբևէ եղե՞լ է մի գաղափար, որը խոստումնալից է թվացել, իսկ հետո գործնականում ձախողվել:

Ժայռ: Իհարկե! Գրանցման տեղաբաշխումը մի տարածք է, որտեղ դուք փորձում եք գտնել որոշ էվրիստիկա՝ NP-ամբողջական խնդիրը լուծելու համար: Եվ դուք երբեք չեք կարող հասնել կատարյալ լուծման, այնպես չէ՞: Սա ուղղակի անհնար է։ Նայեք, Ahead of Time կոմպիլյացիան - այն նույնպես վատ է աշխատում: Այստեղ խոսակցությունը որոշ միջին դեպքերի մասին է։ Տիպիկ կատարողականության մասին, այնպես որ կարող եք գնալ և չափել մի բան, որը, ըստ ձեզ, լավ բնորոշ կատարողականություն է. ի վերջո, դուք աշխատում եք այն բարելավելու ուղղությամբ: Գրանցման բաշխումը կատարողականի մասին թեմա է: Երբ դուք ունեք առաջին նախատիպը, այն աշխատում է և ներկում է այն, ինչ անհրաժեշտ է, սկսվում է կատարողական աշխատանքը: Դուք պետք է սովորեք լավ չափել: Ինչու՞ է դա կարևոր: Եթե ​​ունեք հստակ տվյալներ, կարող եք նայել տարբեր ոլորտներ և տեսնել. այո, դա օգնեց այստեղ, բայց այստեղ ամեն ինչ կոտրվեց: Մի քանի լավ գաղափարներ են առաջանում, դուք ավելացնում եք նոր էվրիստիկա և հանկարծ ամեն ինչ սկսում է միջինում մի փոքր ավելի լավ աշխատել: Կամ չի սկսվում: Ես ունեի մի շարք դեպքեր, երբ մենք պայքարում էինք հինգ տոկոս կատարողականի համար, որը տարբերում էր մեր զարգացումը նախորդ հատկացնողից: Եվ ամեն անգամ այսպես է թվում՝ ինչ-որ տեղ հաղթում ես, մի ​​տեղ՝ պարտվում։ Եթե ​​ունեք կատարողականի վերլուծության լավ գործիքներ, կարող եք գտնել կորցրած գաղափարները և հասկանալ, թե ինչու են դրանք ձախողվում: Միգուցե արժե ամեն ինչ թողնել այնպես, ինչպես կա, կամ գուցե ավելի լուրջ մոտենալ կարգավորելուն, կամ դուրս գալ և այլ բան շտկել: Դա մի ամբողջ փունջ բաներ. Ես արել եմ այս հիանալի հաքը, բայց ինձ նաև պետք է այս մեկը, և այս մեկը և այս մեկը, և դրանց ընդհանուր համադրությունը որոշակի բարելավումներ է տալիս: Իսկ միայնակները կարող են ձախողվել: Սա NP- ամբողջական խնդիրների վրա կատարողական աշխատանքի բնույթն է:

ՎլադիմիրՄարդուն մոտ տպավորություն է ստեղծվում, որ հատկացուցիչների մեջ ներկելը խնդիր է, որն արդեն լուծված է: Դե, դա ձեզ համար է որոշված, դատելով ձեր ասածից, ուրեմն արժե՞ այդ դեպքում…

ԺայռԴա որպես այդպիսին չի լուծվում։ Դուք պետք է այն դարձնեք «լուծված»: Բարդ խնդիրներ կան, և դրանք լուծելու կարիք ունեն։ Երբ դա արվի, ժամանակն է աշխատել արտադրողականության վրա: Դուք պետք է համապատասխանաբար մոտենաք այս աշխատանքին. կատարեք հենանիշեր, հավաքեք չափումներ, բացատրեք իրավիճակներ, երբ, երբ վերադարձաք նախորդ տարբերակին, ձեր հին հաքը նորից սկսեց աշխատել (կամ հակառակը, դադարեց): Եվ մի հանձնվեք, քանի դեռ չեք հասել ինչ-որ բանի: Ինչպես արդեն ասացի, եթե կան թույն գաղափարներ, որոնք չեն աշխատել, բայց գաղափարների ռեգիստրների տեղաբաշխման ոլորտում դա մոտավորապես անվերջ է։ Դուք կարող եք, օրինակ, կարդալ գիտական ​​հրապարակումներ: Չնայած հիմա այս տարածքը սկսել է շատ ավելի դանդաղ շարժվել ու ավելի պարզ է դարձել, քան իր երիտասարդության տարիներին։ Այնուամենայնիվ, կան անթիվ մարդիկ, ովքեր աշխատում են այս ոլորտում, և նրանց բոլոր գաղափարներն արժե փորձել, նրանք բոլորը սպասում են թեւերի մեջ։ Եվ դուք չեք կարող ասել, թե որքան լավն են դրանք, եթե չփորձեք դրանք: Որքան լավ են նրանք ինտեգրվում ձեր հատկացնողի մնացած ամեն ինչի հետ, քանի որ հատկացնողը շատ բաներ է անում, և որոշ գաղափարներ չեն աշխատի ձեր կոնկրետ հատկացուցիչում, բայց մեկ այլ հատկացուցիչում դրանք հեշտությամբ կաշխատեն: Բաշխողի համար հաղթելու հիմնական միջոցը դանդաղ իրերը դուրս հանելն է հիմնական ուղուց և ստիպել նրան բաժանվել դանդաղ ուղիների սահմաններով: Այսպիսով, եթե ցանկանում եք գործարկել GC, գնացեք դանդաղ ճանապարհով, ապաօպտիմիզացրեք, բացառություն արեք, այդ ամենը, դուք գիտեք, որ այս բաները համեմատաբար հազվադեպ են: Եվ դրանք իսկապես հազվադեպ են, ես ստուգեցի: Դուք լրացուցիչ աշխատանք եք կատարում, և դա վերացնում է այս դանդաղ ուղիների շատ սահմանափակումներ, բայց դա իրականում կարևոր չէ, քանի որ դրանք դանդաղ են և հազվադեպ են ճանապարհորդում: Օրինակ, զրոյական ցուցիչ - դա երբեք չի լինում, այնպես չէ՞: Տարբեր բաների համար պետք է ունենալ մի քանի ճանապարհ, բայց դրանք չպետք է խանգարեն հիմնականին: 

ՎլադիմիրԻ՞նչ եք կարծում բազմամիջուկների մասին, երբ միանգամից հազարավոր միջուկներ կան: Արդյո՞ք սա օգտակար բան է:

ԺայռGPU-ի հաջողությունը ցույց է տալիս, որ այն բավականին օգտակար է:

ՎլադիմիրՆրանք բավականին մասնագիտացված են: Ինչ վերաբերում է ընդհանուր նշանակության պրոցեսորներին:

ԺայռԴե, դա Ազուլի բիզնես մոդելն էր: Պատասխանը վերադարձավ մի դարաշրջանում, երբ մարդիկ իսկապես սիրում էին կանխատեսելի կատարումը: Այն ժամանակ դժվար էր զուգահեռ կոդ գրելը։ H2O կոդավորման մոդելը շատ լայնածավալ է, բայց դա ընդհանուր նշանակության մոդել չէ: Թերևս մի փոքր ավելի ընդհանուր, քան GPU օգտագործելիս: Խոսքը նման բան մշակելու բարդությա՞ն մասին է, թե՞ օգտագործելու բարդության: Օրինակ, Azul-ը ինձ մի հետաքրքիր դաս տվեց, բավականին ոչ ակնհայտ՝ փոքր քեշերը նորմալ են։ 

Կյանքի ամենամեծ մարտահրավերը

ՎլադիմիրԻնչ վերաբերում է ոչ տեխնիկական մարտահրավերներին:

ԺայռԱմենամեծ մարտահրավերը մարդկանց հետ բարի և բարի չլինելն էր: Եվ արդյունքում ես անընդհատ հայտնվում էի ծայրահեղ կոնֆլիկտային իրավիճակներում։ Նրանք, որտեղ ես գիտեի, որ ամեն ինչ սխալ է ընթանում, բայց չգիտեի, թե ինչպես առաջ շարժվել այդ խնդիրների հետ և չէի կարող հաղթահարել դրանք: Այսպես առաջացան բազմաթիվ երկարաժամկետ խնդիրներ՝ տասնամյակներ տեւած։ Այն, որ Java-ն ունի C1 և C2 կոմպիլյատորներ, դրա ուղղակի հետևանքն է։ Այն, որ Java-ում տասը տարի անընդմեջ բազմաստիճան կոմպիլացիա չի եղել, նույնպես ուղղակի հետևանք է։ Ակնհայտ է, որ մեզ նման համակարգ էր պետք, բայց թե ինչու այն չկար, ակնհայտ չէ։ Ես խնդիրներ ունեի մեկ ինժեների հետ... կամ ինժեներների խմբի հետ: Ժամանակին, երբ սկսեցի աշխատել Sun-ում, ես... Լավ, ոչ միայն այն ժամանակ, ես ընդհանրապես միշտ իմ կարծիքն ունեմ ամեն ինչի մասին։ Եվ ես կարծում էի, որ ճիշտ է, որ դուք կարող եք պարզապես վերցնել ձեր այս ճշմարտությունը և ասել այն գլխիվայր: Հատկապես, որ շատ ժամանակ ես ցնցող ճիշտ էի: Իսկ եթե այս մոտեցումը ձեզ դուր չի գալիս... հատկապես, եթե ակնհայտորեն սխալվում եք և անհեթեթություն եք անում... Ընդհանրապես, քչերը կարող էին հանդուրժել հաղորդակցության այս ձևը: Չնայած ոմանք կարող էին, ինչպես ես: Ես իմ ամբողջ կյանքը կառուցել եմ մերիտոկրատական ​​սկզբունքների վրա։ Եթե ​​սխալ բան ցույց տաք, ես անմիջապես կշրջվեմ ու կասեմ՝ հիմարություն ասացիք։ Միաժամանակ, իհարկե, հայցում եմ ձեր ներողամտությունը և այդ ամենը, կնշեմ արժանիքները, եթե այդպիսիք կան, և կձեռնարկեն այլ ճիշտ գործողություններ։ Մյուս կողմից, ես ցնցող ճիշտ եմ ընդհանուր ժամանակի ցնցող մեծ տոկոսի վերաբերյալ: Եվ դա այնքան էլ լավ չի ստացվում մարդկանց հետ հարաբերություններում: Ես չեմ փորձում լավ լինել, բայց հարցը տալիս եմ կոպիտ. «Սա երբեք չի աշխատի, քանի որ մեկ, երկու և երեք»: Եվ նրանք ասում էին. «Օ՜»։ Կային նաև այլ հետևանքներ, որոնք, հավանաբար, ավելի լավ է անտեսել. օրինակ՝ դրանք, որոնք հանգեցրին կնոջիցս ամուսնալուծության և դրանից հետո տասը տարվա դեպրեսիայի:

Մարտահրավերը պայքար է մարդկանց հետ, նրանց ընկալմամբ, թե ինչ կարող ես կամ ինչ չես կարող անել, ինչն է կարևոր և ինչը՝ ոչ: Կոդավորման ոճի հետ կապված բազմաթիվ մարտահրավերներ կային: Ես դեռ շատ կոդ եմ գրում, և այդ օրերին ես նույնիսկ ստիպված էի դանդաղեցնել, քանի որ ես չափազանց շատ զուգահեռ առաջադրանքներ էի կատարում և դրանք վատ էի անում, փոխարենը կենտրոնանալու մեկի վրա: Հետ նայելով, ես գրեցի Java JIT հրամանի կոդի կեսը՝ C2 հրամանը: Հաջորդ ամենաարագ կոդավորողը գրեց կես դանդաղ, հաջորդ կեսը դանդաղ, և դա էքսպոնենցիալ անկում էր: Այս շարքի յոթերորդ մարդը շատ, շատ դանդաղ էր, դա միշտ էլ պատահում է: Ես շոշափեցի շատ կոդ: Ես նայեցի, թե ով ինչ է գրել, առանց բացառության, նայեցի նրանց ծածկագրին, վերանայեցի նրանցից յուրաքանչյուրը և դեռ շարունակեցի ինքս ավելի շատ գրել, քան նրանցից որևէ մեկը: Այս մոտեցումը մարդկանց հետ այնքան էլ լավ չի աշխատում: Որոշ մարդկանց սա դուր չի գալիս: Իսկ երբ չեն կարողանում գլուխ հանել, սկսվում են ամենատարբեր բողոքները: Օրինակ, ինձ մի անգամ ասացին դադարեցնել կոդավորումը, քանի որ ես չափազանց շատ կոդ էի գրում, և դա վտանգում էր թիմին, և ինձ համար այս ամենը կատակ էր թվում. Կկորցնեմ միայն կես թիմեր: Մյուս կողմից, եթե ես շարունակեմ կոդ գրել, և դու կորցնես թիմի կեսը, դա շատ վատ կառավարում է թվում: Ես երբեք իսկապես չեմ մտածել այդ մասին, երբեք չեմ խոսել դրա մասին, բայց դա դեռ ինչ-որ տեղ իմ գլխում էր: Մտքումս պտտվում էր միտքս. «Դուք բոլորդ կատակո՞ւմ եք ինձ»: Այսպիսով, ամենամեծ խնդիրը ես էի և իմ հարաբերությունները մարդկանց հետ։ Հիմա ես ինձ շատ ավելի լավ եմ հասկանում, ես երկար ժամանակ ծրագրավորողների թիմում էի, և հիմա ուղղակիորեն ասում եմ մարդկանց. այստեղ? Եվ երբ սկսեցին զբաղվել դրանով, ամեն ինչ ստացվեց։ Իրականում ես ոչ վատն եմ, ոչ լավը, ես ոչ մի վատ մտադրություն կամ եսասիրական նկրտում չունեմ, դա ուղղակի իմ էությունն է, և ես պետք է ինչ-որ կերպ ապրեմ դրա հետ:

AndrewՎերջերս բոլորը սկսեցին խոսել ինտրովերտների համար ինքնաճանաչման և ընդհանրապես փափուկ հմտությունների մասին: Ի՞նչ կարող եք ասել այս մասին։

ԺայռԱյո, դա այն խորաթափանցությունն ու դասն էր, որը ես քաղեցի կնոջիցս ամուսնալուծությունից: Այն, ինչ ես սովորեցի ամուսնալուծությունից, ինքս ինձ հասկանալն էր: Այսպես սկսեցի հասկանալ այլ մարդկանց։ Հասկացեք, թե ինչպես է այս փոխազդեցությունը գործում: Սա հանգեցրեց բացահայտումների մեկը մյուսի հետևից: Կար գիտակցություն, թե ով եմ ես և ինչ եմ ներկայացնում: Ի՞նչ եմ ես անում. կա՛մ ես զբաղված եմ առաջադրանքով, կա՛մ խուսափում եմ կոնֆլիկտից, կա՛մ մեկ այլ բան, և ինքնագիտակցության այս մակարդակն իսկապես օգնում է ինձ վերահսկել: Դրանից հետո ամեն ինչ շատ ավելի հեշտ է ընթանում: Մի բան, որ ես հայտնաբերեցի ոչ միայն իմ, այլ նաև այլ ծրագրավորողների մոտ, դա մտքերը բառացիորեն արտահայտելու անկարողությունն է, երբ դուք գտնվում եք հուզական սթրեսի վիճակում: Օրինակ, դուք նստած եք կոդավորումով, հոսանքի վիճակում, և հետո նրանք վազելով գալիս են ձեզ մոտ և սկսում են հիստերիկ բղավել, որ ինչ-որ բան կոտրվել է, և այժմ ձեր դեմ ծայրահեղ միջոցներ կձեռնարկվեն: Եվ դուք չեք կարող որևէ բառ ասել, քանի որ գտնվում եք հուզական սթրեսի վիճակում: Ձեռք բերված գիտելիքները թույլ են տալիս պատրաստվել այս պահին, գոյատևել այն և անցնել նահանջի պլանի, որից հետո կարող ես ինչ-որ բան անել։ Այսպիսով, այո, երբ սկսում ես հասկանալ, թե ինչպես է այդ ամենն աշխատում, դա կյանքը փոխող հսկայական իրադարձություն է: 
Ես ինքս ճիշտ բառեր չէի գտնում, բայց հիշում էի գործողությունների հաջորդականությունը։ Բանն այն է, որ այս արձագանքը որքան ֆիզիկական է, որքան բանավոր, և ձեզ տարածք է պետք: Նման տարածություն՝ զեն իմաստով։ Սա հենց այն է, ինչ պետք է բացատրել, իսկ հետո անմիջապես մի կողմ քաշվել՝ զուտ ֆիզիկապես հեռանալ: Երբ բանավոր լռում եմ, կարող եմ էմոցիոնալ կերպով մշակել իրավիճակը։ Քանի որ ադրենալինը հասնում է ձեր ուղեղին, ձեզ միացնում է կռվի կամ թռիչքի ռեժիմի, դուք այլևս չեք կարող որևէ բան ասել, ոչ, հիմա դուք ապուշ եք, մտրակող ինժեներ, անկարող եք պատշաճ պատասխան տալ կամ նույնիսկ դադարեցնել հարձակումը, և հարձակվողն ազատ է: նորից ու նորից հարձակվել։ Նախ պետք է նորից դառնաս ինքդ քեզ, վերականգնես վերահսկողությունը, դուրս գաս «կռվել կամ փախչել» ռեժիմից։

Իսկ դրա համար խոսքային տարածություն է պետք։ Պարզապես ազատ տարածք: Եթե ​​դու ընդհանրապես որևէ բան ես ասում, ապա կարող ես հենց այդպես էլ ասել, իսկ հետո գնալ և իսկապես «տարածք» գտնել քեզ համար. գնալ զբոսնելու այգում, փակվել ցնցուղի մեջ, դա կարևոր չէ: Գլխավորը ժամանակավորապես անջատվելն է այդ իրավիճակից։ Հենց որ գոնե մի քանի վայրկյանով անջատես, վերահսկողությունը վերադառնում է, սկսում ես սթափ մտածել։ «Լավ, ես ինչ-որ ապուշ չեմ, ես հիմարություններ չեմ անում, ես բավականին օգտակար մարդ եմ»: Երբ դուք կարողացաք ինքներդ ձեզ համոզել, ժամանակն է անցնել հաջորդ փուլին՝ հասկանալ, թե ինչ է տեղի ունեցել: Ձեր վրա հարձակվել են, հարձակումը եկել է այնտեղից, որտեղ դուք չէիք սպասում, դա անազնիվ, ստոր դարան էր։ Սա վատ է: Հաջորդ քայլը հասկանալն է, թե ինչու էր հարձակվողին դա անհրաժեշտ: Իսկապես, ինչու? Միգուցե այն պատճառով, որ նա ի՞նքն է կատաղած։ Ինչու՞ է նա կատաղած: Օրինակ, որովհետև ինքն իրեն խաբել է և չի՞ կարողանում ընդունել պատասխանատվությունը։ Սա է ամբողջ իրավիճակը զգույշ վարելու ճանապարհը: Բայց սա պահանջում է մանևրելու տեղ, բանավոր տարածություն: Հենց առաջին քայլը բանավոր շփումը խզելն է։ Խուսափեք բառերով քննարկելուց: Չեղարկեք այն, հեռացեք որքան հնարավոր է շուտ: Եթե ​​դա հեռախոսազրույց է, պարզապես անջատեք հեռախոսը. սա այն հմտությունն է, որը ես սովորել եմ նախկին կնոջս հետ շփվելուց: Եթե ​​խոսակցությունը ոչ մի լավ տեղ չի տանում, պարզապես ասեք «ցտեսություն» և անջատեք հեռախոսը: Հեռախոսի մյուս կողմից՝ «բլա բլա բլա», պատասխանում ես՝ «այո, ցտեսություն»: և կախել հեռախոսը: Դուք պարզապես ավարտում եք զրույցը: Հինգ րոպե անց, երբ խելամիտ մտածելու ունակությունը վերադառնում է քեզ, դու մի փոքր զովացել ես, հնարավոր է դառնում մտածել ամեն ինչի մասին, թե ինչ է եղել և ինչ է լինելու հետո։ Եվ սկսեք ձևակերպել մտածված պատասխան, այլ ոչ թե պարզապես արձագանքել զգացմունքներից դրդված: Ինձ համար ինքնաճանաչման բեկումնային էր հենց այն, որ հուզական սթրեսի դեպքում ես չեմ կարող խոսել։ Դուրս գալ այս վիճակից, մտածել և պլանավորել, թե ինչպես արձագանքել և փոխհատուցել խնդիրները. սրանք ճիշտ քայլեր են այն դեպքում, երբ չես կարողանում խոսել։ Ամենահեշտ ճանապարհը փախչելն է այն իրավիճակից, որում դրսևորվում է հուզական սթրեսը և պարզապես դադարեցնել այս սթրեսին մասնակցելը։ Դրանից հետո դուք կարող եք մտածել, երբ կարող եք մտածել, դառնում եք կարող խոսել և այլն:

Ի դեպ, դատարանում հակառակորդ փաստաբանը փորձում է դա անել ձեզ հետ, հիմա պարզ է, թե ինչու: Որովհետև նա կարողություն ունի քեզ ճնշելու այնպիսի վիճակի, որ դու չես կարող, օրինակ, քո անունն անգամ արտասանել։ Շատ իրական իմաստով դուք չեք կարողանա խոսել: Եթե ​​դա պատահի ձեզ հետ, և եթե գիտեք, որ դուք կհայտնվեք մի վայրում, որտեղ բանավոր կռիվներ են մոլեգնում, այնպիսի վայրում, ինչպիսին դատարանն է, ապա կարող եք գալ ձեր փաստաբանի հետ։ Փաստաբանը կկանգնի ձեր օգտին և կդադարեցնի բանավոր հարձակումը և դա կանի լիովին օրինական ճանապարհով, և կորցրած Զեն տարածքը կվերադառնա ձեզ: Օրինակ, ես ստիպված էի մի քանի անգամ զանգահարել իմ ընտանիքին, դատավորը բավականին բարեհամբույր էր վերաբերվում դրան, բայց հակառակորդ փաստաբանը բղավեց և բղավեց ինձ վրա, ես նույնիսկ չկարողացա որևէ բառ ասել: Այս դեպքերում միջնորդի օգտագործումն ինձ համար լավագույնն է: Միջնորդը դադարեցնում է այս ամբողջ ճնշումը, որը թափվում է ձեզ վրա շարունակական հոսքով, դուք գտնում եք անհրաժեշտ Զեն տարածությունը, և դրա հետ միասին վերադառնում է խոսելու ունակությունը: Սա գիտելիքի մի ամբողջ ոլորտ է, որտեղ շատ բան կա ուսումնասիրելու, շատ բան բացահայտելու քո ներսում, և այս ամենը վերածվում է բարձր մակարդակի ռազմավարական որոշումների, որոնք տարբեր են տարբեր մարդկանց համար: Որոշ մարդիկ չունեն վերը նկարագրված խնդիրները, սովորաբար այն մարդիկ, ովքեր պրոֆեսիոնալ վաճառողներ են, դրանք չունեն: Բոլոր այս մարդիկ, ովքեր իրենց ապրուստը վաստակում են խոսքերով` հայտնի երգիչներ, բանաստեղծներ, կրոնական առաջնորդներ և քաղաքական գործիչներ, նրանք միշտ ասելիք ունեն։ Նրանք նման խնդիրներ չունեն, բայց ես ունեմ։

Andrew- Դա... անսպասելի էր։ Հիանալի, մենք արդեն շատ ենք խոսել, և ժամանակն է ավարտել այս հարցազրույցը: Մենք անպայման կհանդիպենք համաժողովին և կկարողանանք շարունակել այս երկխոսությունը։ Կհանդիպենք Hydra-ում:

Քլիֆի հետ զրույցը կարող եք շարունակել Hydra 2019 կոնֆերանսում, որը կանցկացվի 11 թվականի հուլիսի 12-2019-ը Սանկտ Պետերբուրգում։ Նա կգա զեկույցով «Azul ապարատային գործարքային հիշողության փորձ». Տոմսերը կարելի է ձեռք բերել պաշտոնական կայքում.

Source: www.habr.com

Добавить комментарий