Goeie onderhoud met Cliff Click, die vader van JIT-samestelling in Java

Goeie onderhoud met Cliff Click, die vader van JIT-samestelling in JavaCliff Klik — CTO van Cratus (IoT-sensors vir prosesverbetering), stigter en medestigter van verskeie opstartings (insluitend Rocket Realtime School, Neurensic en H2O.ai) met verskeie suksesvolle uitgange. Cliff het sy eerste samesteller op ouderdom 15 geskryf (Pascal vir die TRS Z-80)! Hy is veral bekend vir sy werk op C2 in Java (die See van Nodes IR). Hierdie samesteller het die wêreld gewys dat JIT hoë kwaliteit kode kan produseer, wat een van die faktore was in die opkoms van Java as een van die belangrikste moderne sagteware platforms. Toe het Cliff Azul Systems gehelp om 'n 864-kern-hoofraamwerk te bou met suiwer Java-sagteware wat GC-pouses op 'n 500-gigagreep-hoop binne 10 millisekondes ondersteun. Oor die algemeen het Cliff daarin geslaag om aan alle aspekte van die JVM te werk.

 
Hierdie habrapost is 'n wonderlike onderhoud met Cliff. Ons sal oor die volgende onderwerpe gesels:

  • Gaan oor na laevlak-optimalisasies
  • Hoe om 'n groot herfaktorering te doen
  • Koste model
  • Lae-vlak optimalisering opleiding
  • Praktiese voorbeelde van prestasieverbetering
  • Hoekom jou eie programmeertaal skep
  • Prestasie-ingenieur Loopbaan
  • Tegniese uitdagings
  • 'n Bietjie oor registertoewysing en multi-kerns
  • Die grootste uitdaging in die lewe

Die onderhoud word gevoer deur:

  • Andrey Satarin van Amazon Web Services. In sy loopbaan het hy daarin geslaag om in heeltemal verskillende projekte te werk: hy het die NewSQL-verspreide databasis in Yandex getoets, 'n wolkopsporingstelsel in Kaspersky Lab, 'n multiplayer-speletjie in Mail.ru en 'n diens vir die berekening van buitelandse valutapryse in Deutsche Bank. Stel belang in die toets van grootskaalse backend en verspreide stelsels.
  • Vladimir Sitnikov van Netcracker. Tien jaar se werk aan die werkverrigting en skaalbaarheid van NetCracker OS, sagteware wat deur telekommunikasie-operateurs gebruik word om netwerk- en netwerktoerustingbestuursprosesse te outomatiseer. Stel belang in Java en Oracle Database prestasie kwessies. Skrywer van meer as 'n dosyn prestasieverbeterings in die amptelike PostgreSQL JDBC-bestuurder.

Gaan oor na laevlak-optimalisasies

Andrew: Jy is 'n groot naam in die wêreld van JIT-samestelling, Java en prestasiewerk in die algemeen, reg? 

Klip: Dit is so!

Andrew: Kom ons begin met 'n paar algemene vrae oor uitvoeringswerk. Wat dink jy van die keuse tussen hoëvlak- en laevlakoptimalisasies soos om op die SVE-vlak te werk?

Klip: Ja, alles is eenvoudig hier. Die vinnigste kode is die een wat nooit loop nie. Daarom moet jy altyd van 'n hoë vlak begin, werk aan algoritmes. 'n Beter O-notasie sal 'n swakker O-notasie klop, tensy 'n paar voldoende groot konstantes ingryp. Lae-vlak dinge gaan laaste. Tipies, as jy die res van jou stapel goed genoeg geoptimaliseer het en daar is nog 'n paar interessante goed oor, is dit 'n lae vlak. Maar hoe om van 'n hoë vlak te begin? Hoe weet jy dat genoeg hoëvlakwerk gedoen is? Wel... geen manier nie. Daar is geen klaargemaakte resepte nie. Jy moet die probleem verstaan, besluit wat jy gaan doen (sodat jy nie in die toekoms onnodige stappe doen nie) en dan kan jy die profileerder ontbloot, wat iets nuttigs kan sê. Op 'n stadium besef jy self dat jy van onnodige dinge ontslae geraak het en dit is tyd om 'n bietjie lae-vlak fyninstelling te doen. Dit is beslis 'n spesiale soort kuns. Daar is baie mense wat onnodige dinge doen, maar so vinnig beweeg dat hulle nie tyd het om oor produktiwiteit te bekommer nie. Maar dit is totdat die vraag reguit ontstaan. Gewoonlik 99% van die tyd gee niemand om wat ek doen nie, tot die oomblik wanneer 'n belangrike ding op die kritieke pad kom waaroor niemand omgee nie. En hier begin almal jou neul oor "hoekom dit nie van die begin af perfek gewerk het nie." Oor die algemeen is daar altyd iets om te verbeter in prestasie. Maar 99% van die tyd het jy geen leidrade nie! Jy probeer net iets laat werk en in die proses vind jy uit wat belangrik is. Jy kan nooit vooraf weet dat hierdie stuk perfek moet wees nie, so eintlik moet jy perfek wees in alles. Maar dit is onmoontlik en jy doen dit nie. Daar is altyd baie dinge om reg te maak – en dit is heeltemal normaal.

Hoe om 'n groot herfaktorering te doen

Andrew: Hoe werk jy aan 'n opvoering? Dit is 'n deurkruisende probleem. Moes jy byvoorbeeld al ooit werk aan probleme wat ontstaan ​​uit die kruising van baie bestaande funksionaliteit?

Klip: Ek probeer dit vermy. As ek weet dat prestasie 'n probleem sal wees, dink ek daaroor voor ek begin kodeer, veral met datastrukture. Maar dikwels ontdek jy dit alles baie later. En dan moet jy tot uiterste maatreëls gaan en doen wat ek noem "herskryf en oorwin": jy moet 'n groot genoeg stuk gryp. Sommige van die kode sal steeds herskryf moet word weens prestasieprobleme of iets anders. Wat ook al die rede vir die herskryf van kode, dit is byna altyd beter om 'n groter stuk as 'n kleiner stuk te herskryf. Op hierdie oomblik begin almal bewe van vrees: "O my God, jy kan nie soveel kode raak nie!" Maar in werklikheid werk hierdie benadering byna altyd baie beter. Jy moet dadelik 'n groot probleem aanpak, 'n groot sirkel daarom trek en sê: Ek sal alles binne-in die sirkel oorskryf. Die rand is baie kleiner as die inhoud daarin wat vervang moet word. En as so 'n afbakening van grense jou toelaat om die werk binne perfek te doen, is jou hande vry, doen wat jy wil. Sodra jy die probleem verstaan, is die herskryfproses baie makliker, so vat 'n groot hap!
Terselfdertyd, wanneer jy 'n groot herskryf doen en besef dat prestasie 'n probleem gaan wees, kan jy dadelik daaroor begin bekommer. Dit verander gewoonlik in eenvoudige dinge soos "moenie data kopieer nie, bestuur data so eenvoudig as moontlik, maak dit klein." In groot herskrywings is daar standaard maniere om werkverrigting te verbeter. En hulle draai byna altyd om data.

Koste model

Andrew: In een van die podcasts het jy gepraat oor kostemodelle in die konteks van produktiwiteit. Kan jy verduidelik wat jy hiermee bedoel het?

Klip: Sekerlik. Ek is gebore in 'n era toe verwerker se werkverrigting uiters belangrik was. En hierdie era keer weer terug – die noodlot is nie sonder ironie nie. Ek het begin lewe in die dae van agtbis-masjiene; my eerste rekenaar het met 256 grepe gewerk. Presies bytes. Alles was baie klein. Instruksies moes getel word, en soos ons begin opskuif in die programmeertaalstapel, het die tale meer en meer aangeneem. Daar was Assembler, toe Basic, toe C, en C het vir baie van die besonderhede gesorg, soos registertoekenning en instruksiekeuse. Maar alles was baie duidelik daar, en as ek 'n wyser na 'n instansie van 'n veranderlike gemaak het, dan sou ek las kry, en die koste van hierdie instruksie is bekend. Die hardeware produseer 'n sekere aantal masjiensiklusse, so die uitvoeringspoed van verskillende dinge kan eenvoudig bereken word deur al die instruksies wat jy gaan uitvoer, bymekaar te tel. Elke vergelyking/toets/tak/oproep/laai/winkel kan opgetel word en gesê: dit is die uitvoeringstyd vir jou. Wanneer jy werk aan die verbetering van prestasie, sal jy beslis aandag gee aan watter getalle ooreenstem met klein warm siklusse. 
Maar sodra jy oorskakel na Java, Python en soortgelyke dinge, beweeg jy baie vinnig weg van laevlak hardeware. Wat is die koste om 'n getter in Java te bel? As JIT in HotSpot korrek is ingelyn, sal dit laai, maar as dit dit nie gedoen het nie, sal dit 'n funksie-oproep wees. Aangesien die oproep op 'n warm lus is, sal dit alle ander optimaliserings in daardie lus ignoreer. Daarom sal die werklike koste baie hoër wees. En jy verloor dadelik die vermoë om na 'n stukkie kode te kyk en te verstaan ​​dat ons dit moet uitvoer in terme van verwerker se klokspoed, geheue en kas wat gebruik word. Dit alles word net interessant as jy werklik in die uitvoering kom.
Nou bevind ons ons in 'n situasie waar verwerkersnelhede vir 'n dekade skaars toegeneem het. Die ou dae is terug! Jy kan nie meer staatmaak op goeie enkeldraadwerkverrigting nie. Maar as jy skielik by parallelle rekenaars kom, is dit ongelooflik moeilik, almal kyk na jou soos James Bond. Tienvoudige versnellings kom hier gewoonlik voor op plekke waar iemand iets deurmekaar gemaak het. Gelyktydigheid verg baie werk. Om daardie XNUMXx versnelling te kry, moet jy die kostemodel verstaan. Wat en hoeveel kos dit? En om dit te doen, moet jy verstaan ​​hoe die tong op die onderliggende hardeware pas.
Martin Thompson het 'n wonderlike woord vir sy blog gekies Meganiese simpatie! Jy moet verstaan ​​wat die hardeware gaan doen, presies hoe dit dit sal doen en hoekom dit in die eerste plek doen wat dit doen. Deur dit te gebruik, is dit redelik maklik om instruksies te begin tel en uit te vind waarheen die uitvoeringstyd gaan. As jy nie die toepaslike opleiding het nie, soek jy net 'n swart kat in 'n donker kamer. Ek sien mense wat die heeltyd prestasie optimaliseer wat geen idee het wat de hel hulle doen nie. Hulle ly baie en maak nie veel vordering nie. En wanneer ek dieselfde stukkie kode neem, 'n paar klein hakies inglip en 'n vyf- of tienvoudige versnelling kry, is hulle soos: wel, dit is nie regverdig nie, ons het reeds geweet jy is beter. Wonderlik. Waarvan praat ek... die kostemodel gaan oor watter soort kode jy skryf en hoe vinnig dit gemiddeld in die groot prentjie loop.

Andrew: En hoe kan jy so 'n volume in jou kop hou? Word dit bereik met meer ervaring, of? Waar kom sulke ervaring vandaan?

Klip: Wel, ek het nie my ervaring op die maklikste manier gekry nie. Ek het in Assembly geprogrammeer in die dae toe jy elke enkele instruksie kon verstaan. Dit klink dom, maar sedertdien het die Z80-instruksiestel altyd in my kop gebly, in my geheue. Ek onthou nie mense se name binne 'n minuut nadat ek gepraat het nie, maar ek onthou kode wat 40 jaar gelede geskryf is. Dit is snaaks, dit lyk soos 'n sindroom "idioot wetenskaplike".

Lae-vlak optimalisering opleiding

Andrew: Is daar 'n makliker manier om in te kom?

Klip: Ja en nee. Die hardeware wat ons almal gebruik, het mettertyd nie soveel verander nie. Almal gebruik x86, met die uitsondering van Arm-slimfone. As jy nie 'n soort hardekern-inbedding doen nie, doen jy dieselfde ding. Goed, volgende. Die instruksies het ook vir eeue nie verander nie. Jy moet iets in Assembly gaan skryf. Nie veel nie, maar genoeg om te begin verstaan. Jy glimlag, maar ek praat heeltemal ernstig. Jy moet die ooreenkoms tussen taal en hardeware verstaan. Daarna moet jy 'n bietjie gaan skryf en 'n klein speelgoedsamesteller maak vir 'n bietjie speelgoedtaal. Speelgoedagtig beteken dat dit binne 'n redelike tyd gemaak moet word. Dit kan super eenvoudig wees, maar dit moet instruksies genereer. Die handeling om 'n instruksie te genereer sal jou help om die kostemodel vir die brug tussen die hoëvlakkode wat almal skryf en die masjienkode wat op die hardeware loop, te verstaan. Hierdie korrespondensie sal in die brein ingebrand word wanneer die samesteller geskryf word. Selfs die eenvoudigste samesteller. Daarna kan jy begin kyk na Java en die feit dat sy semantiese kloof baie dieper is, en dit is baie moeiliker om brûe daaroor te bou. In Java is dit baie moeiliker om te verstaan ​​of ons brug goed of sleg uitgedraai het, wat dit sal laat uitmekaar val en wat nie. Maar jy het 'n soort beginpunt nodig waar jy na die kode kyk en verstaan: "ja, hierdie getter moet elke keer ingelyn word." En dan blyk dit dat dit soms gebeur, behalwe vir die situasie wanneer die metode te groot word, en die JIT alles begin inlyn. Die prestasie van sulke plekke kan onmiddellik voorspel word. Gewoonlik werk getters goed, maar dan kyk jy na groot warm loops en besef dat daar 'n paar funksie-oproepe daar ronddryf wat nie weet wat hulle doen nie. Dit is die probleem met die wydverspreide gebruik van getters, die rede waarom hulle nie ingelyn is nie, is dat dit nie duidelik is of hulle 'n getter is nie. As jy 'n superklein kodebasis het, kan jy dit eenvoudig onthou en dan sê: hierdie is 'n getter, en dit is 'n setter. In 'n groot kodebasis leef elke funksie sy eie geskiedenis, wat oor die algemeen aan niemand bekend is nie. Die profileerder sê dat ons 24% van die tyd op een of ander lus verloor het en om te verstaan ​​wat hierdie lus doen, moet ons na elke funksie binne kyk. Dit is onmoontlik om dit te verstaan ​​sonder om die funksie te bestudeer, en dit vertraag die proses van verstaan ​​ernstig. Dit is hoekom ek nie getters en setters gebruik nie, ek het 'n nuwe vlak bereik!
Waar om die kostemodel te kry? Wel, jy kan natuurlik iets lees... Maar ek dink die beste manier is om op te tree. Om 'n klein samesteller te maak, sal die beste manier wees om die kostemodel te verstaan ​​en dit in jou eie kop te pas. 'n Klein samesteller wat geskik sal wees vir die programmering van 'n mikrogolfoond is 'n taak vir 'n beginner. Wel, ek bedoel, as jy reeds programmeringsvaardighede het, dan behoort dit genoeg te wees. Al hierdie dinge soos om 'n string te ontleed wat jy as 'n soort algebraïese uitdrukking het, instruksies vir wiskundige bewerkings van daar in die regte volgorde te onttrek, die korrekte waardes uit registers te neem - dit alles word gelyktydig gedoen. En terwyl jy dit doen, sal dit in jou brein ingeprent word. Ek dink almal weet wat 'n samesteller doen. En dit sal 'n begrip van die kostemodel gee.

Praktiese voorbeelde van prestasieverbetering

Andrew: Waaraan moet jy nog aandag gee wanneer jy aan produktiwiteit werk?

Klip: Datastrukture. Terloops, ja, ek het lanklaas hierdie klasse gegee... Vuurpylskool. Dit was pret, maar dit het baie moeite geverg, en ek het ook 'n lewe! OK. Dus, in een van die groot en interessante klasse, "Waarheen gaan jou prestasie," het ek studente 'n voorbeeld gegee: twee en 'n half gigagrepe fintech-data is uit 'n CSV-lêer gelees en dan moes hulle die aantal produkte wat verkoop is, bereken . Gereelde bosluismarkdata. UDP-pakkies omgeskakel na teksformaat sedert die 70's. Chicago Mercantile Exchange - allerhande dinge soos botter, mielies, sojabone, sulke dinge. Dit was nodig om hierdie produkte, die aantal transaksies, die gemiddelde volume van beweging van fondse en goedere, ens. Dit is redelik eenvoudige handelswiskunde: vind die produkkode (dit is 1-2 karakters in die hash-tabel), kry die bedrag, voeg dit by een van die handelsstelle, voeg volume by, voeg waarde by, en 'n paar ander dinge. Baie eenvoudige wiskunde. Die speelgoedimplementering was baie eenvoudig: alles is in 'n lêer, ek lees die lêer en beweeg daardeur, verdeel individuele rekords in Java-stringe, soek die nodige dinge daarin en tel dit bymekaar volgens die wiskunde hierbo beskryf. En dit werk teen 'n lae spoed.

Met hierdie benadering is dit duidelik wat aangaan, en parallelle rekenaar sal nie help nie, reg? Dit blyk dat 'n vyfvoudige toename in prestasie bereik kan word bloot deur die regte datastrukture te kies. En dit verras selfs ervare programmeerders! In my spesifieke geval was die truuk dat jy nie geheuetoewysings in 'n warm lus moet maak nie. Wel, dit is nie die volle waarheid nie, maar oor die algemeen - jy moet nie "een keer in X" uitlig wanneer X groot genoeg is nie. Wanneer X twee en 'n half gigagrepe is, moet jy niks "een keer per letter", of "een keer per reël", of "een keer per veld", so iets toeken nie. Dit is waar tyd spandeer word. Hoe werk dit selfs? Stel jou voor dat ek 'n oproep maak String.split() of BufferedReader.readLine(). Readline maak 'n string uit 'n stel grepe wat oor die netwerk gekom het, een keer vir elke lyn, vir elk van die honderde miljoene lyne. Ek neem hierdie lyn, ontleed dit en gooi dit weg. Hoekom gooi ek dit weg - wel, ek het dit reeds verwerk, dis al. Dus, vir elke greep wat van hierdie 2.7G gelees word, sal twee karakters in die reël geskryf word, dit wil sê reeds 5.4G, en ek het hulle vir niks verder nodig nie, so hulle word weggegooi. As jy na die geheuebandwydte kyk, laai ons 2.7G wat deur die geheue en geheuebus in die verwerker gaan, en dan word twee keer soveel gestuur na die lyn wat in die geheue lê, en dit alles word verskeur wanneer elke nuwe lyn geskep word. Maar ek moet dit lees, die hardeware lees dit, selfs al is alles later uitgerafel. En ek moet dit neerskryf, want ek het 'n reël geskep en die kas is vol - die kas kan nie 2.7G akkommodeer nie. So, vir elke grepe wat ek lees, lees ek nog twee grepe en skryf nog twee grepe, en op die ou end het hulle 'n 4:1 verhouding - in hierdie verhouding mors ons geheue bandwydte. En dan blyk dit dat as ek dit doen String.split() – dit is nie die laaste keer dat ek dit doen nie, daar is dalk nog 6-7 velde binne. Die klassieke kode om CSV te lees en dan die snare te ontleed, lei dus tot 'n geheuebandwydtevermorsing van ongeveer 14:1 relatief tot wat jy eintlik wil hê. As jy hierdie keuses weggooi, kan jy 'n vyfvoudige versnelling kry.

En dit is nie so moeilik nie. As jy na die kode van die regte hoek kyk, word dit alles redelik eenvoudig sodra jy die probleem besef. Jy moet nie heeltemal ophou om geheue toe te ken nie: die enigste probleem is dat jy iets toewys en dit sterf dadelik, en langs die pad verbrand dit 'n belangrike hulpbron, wat in hierdie geval geheuebandwydte is. En dit alles lei tot 'n daling in produktiwiteit. Op x86 moet jy gewoonlik verwerkersiklusse aktief verbrand, maar hier het jy al die geheue baie vroeër opgebrand. Die oplossing is om die hoeveelheid ontslag te verminder. 
Die ander deel van die probleem is dat as jy die profiler laat loop wanneer die geheuestreep opraak, net wanneer dit gebeur, wag jy gewoonlik vir die kas om terug te kom, want dit is vol vullis wat jy sopas geproduseer het, al daardie lyne. Daarom word elke laai- of stooroperasie stadig, want dit lei tot kasmis - die hele kas het stadig geword en wag vir vullis om dit te verlaat. Daarom sal die profileerder net warm ewekansige geraas wys wat deur die hele lus gesmeer is - daar sal geen aparte warm instruksie of plek in die kode wees nie. Slegs geraas. En as jy na die GC-siklusse kyk, is hulle almal Young Generation en supervinnig - mikrosekondes of millisekondes maksimum. Al hierdie herinnering sterf immers op slag. Jy ken miljarde gigagrepe toe, en hy sny hulle, en sny hulle, en sny hulle weer. Dit alles gebeur baie vinnig. Dit blyk dat daar goedkoop GC-siklusse is, warm geraas langs die hele siklus, maar ons wil 'n 5x versnelling kry. Op hierdie oomblik behoort iets in jou kop toe te maak en te klink: "waarom is dit?!" Geheuestrookoorloop word nie in die klassieke ontfouter vertoon nie; jy moet die hardeware-werkverrigtingteller-ontfouter laat loop en dit self en direk sien. Maar dit kan nie direk vermoed word van hierdie drie simptome nie. Die derde simptoom is wanneer jy kyk na wat jy uitlig, die profileerder vra, en hy antwoord: "Jy het 'n miljard rye gemaak, maar die GC het gratis gewerk." Sodra dit gebeur, besef jy dat jy te veel voorwerpe geskep het en die hele geheuebaan verbrand het. Daar is 'n manier om dit uit te vind, maar dit is nie voor die hand liggend nie. 

Die probleem is in die datastruktuur: die kaal struktuur onderliggend aan alles wat gebeur, dit is te groot, dit is 2.7G op skyf, so dit is baie ongewens om 'n kopie van hierdie ding te maak - jy wil dit dadelik van die netwerkgreepbuffer af laai in die registers in, om nie vyf keer heen en weer na die reël te lees-skryf nie. Ongelukkig gee Java jou nie by verstek so 'n biblioteek as deel van die JDK nie. Maar dit is triviaal, reg? In wese is dit 5-10 reëls kode wat gebruik sal word om jou eie gebufferde stringlaaier te implementeer, wat die gedrag van die stringklas herhaal, terwyl dit 'n omvou om die onderliggende greepbuffer is. As gevolg hiervan, blyk dit dat jy amper soos met snare werk, maar in werklikheid beweeg wysers na die buffer daarheen, en die rou grepe word nêrens gekopieer nie, en dus word dieselfde buffers oor en oor hergebruik, en die bedryfstelsel neem graag die dinge aan waarvoor dit ontwerp is, soos verborge dubbelbuffering van hierdie greepbuffers, en jy maal nie meer deur 'n eindelose stroom van onnodige data nie. Terloops, verstaan ​​u dat wanneer u met GC werk, dit gewaarborg is dat elke geheuetoewysing nie na die laaste GC-siklus vir die verwerker sigbaar sal wees nie? Daarom kan dit alles onmoontlik in die kas wees, en dan vind 'n 100% gewaarborgde mis plaas. Wanneer jy met 'n wyser werk, op x86, neem die aftrekking van 'n register van die geheue 1-2 kloksiklusse, en sodra dit gebeur, betaal jy, betaal, betaal, want die geheue is alles aan NEGE caches – en dit is die koste van geheuetoewysing. Werklike waarde.

Met ander woorde, datastrukture is die moeilikste ding om te verander. En sodra jy besef dat jy die verkeerde datastruktuur gekies het wat prestasie later sal doodmaak, is daar gewoonlik baie werk om te doen, maar as jy dit nie doen nie, sal dinge erger word. Eerstens moet u oor datastrukture dink, dit is belangrik. Die belangrikste koste hier val op vet datastrukture, wat begin gebruik word in die styl van "Ek het datastruktuur X na datastruktuur Y gekopieer omdat ek die vorm van Y beter hou." Maar die kopieerbewerking (wat goedkoop lyk) mors eintlik geheuebandwydte en dis waar al die vermorste uitvoeringstyd begrawe is. As ek 'n reuse-string JSON het en ek wil dit omskep in 'n gestruktureerde DOM-boom van POJO's of iets, sal die operasie om daardie string te ontleed en die POJO te bou, en dan later weer toegang tot die POJO te kry, onnodige koste tot gevolg hê - dit is nie goedkoop nie. Behalwe as jy baie meer gereeld om POJO's hardloop as wat jy om 'n tou hardloop. Uiteindelik kan jy eerder probeer om die string te dekripteer en net wat jy nodig het van daar af te onttrek, sonder om dit in enige POJO te verander. As dit alles gebeur op 'n pad waarvandaan maksimum prestasie vereis word, geen POJO's vir jou nie, moet jy op een of ander manier direk in die lyn grawe.

Hoekom jou eie programmeertaal skep

Andrew: Jy het gesê om die kostemodel te verstaan, moet jy jou eie taaltjie skryf...

Klip: Nie 'n taal nie, maar 'n samesteller. 'n Taal en 'n samesteller is twee verskillende dinge. Die belangrikste verskil is in jou kop. 

Andrew: Terloops, sover ek weet, eksperimenteer jy met die skep van jou eie tale. Vir wat?

Klip: Want ek kan! Ek is semi-afgetree, so dit is my stokperdjie. Ek het my hele lewe lank ander mense se tale geïmplementeer. Ek het ook baie aan my koderingstyl gewerk. En ook omdat ek probleme in ander tale sien. Ek sien daar is beter maniere om bekende dinge te doen. En ek sou hulle gebruik. Ek is net moeg om probleme in myself te sien, in Java, in Python, in enige ander taal. Ek skryf nou in React Native, JavaScript en Elm as 'n stokperdjie wat nie oor aftrede gaan nie, maar oor aktiewe werk. Ek skryf ook in Python en sal heel waarskynlik aanhou werk aan masjienleer vir Java-agtergronde. Daar is baie gewilde tale en hulle het almal interessante kenmerke. Almal is goed op hul eie manier en jy kan probeer om al hierdie kenmerke bymekaar te bring. So, ek bestudeer dinge wat my interesseer, die gedrag van taal, en probeer om met redelike semantiek vorendag te kom. En tot dusver slaag ek! Op die oomblik sukkel ek met geheue semantiek, want ek wil dit hê soos in C en Java, en 'n sterk geheue model en geheue semantiek vir vragte en store kry. Terselfdertyd, het outomatiese tipe afleiding soos in Haskell. Hier probeer ek om Haskell-agtige tipe afleiding te meng met geheue werk in beide C en Java. Dit is wat ek byvoorbeeld die afgelope 2-3 maande gedoen het.

Andrew: As jy 'n taal bou wat beter aspekte van ander tale neem, dink jy dat iemand die teenoorgestelde sal doen: neem jou idees en gebruik dit?

Klip: Dit is presies hoe nuwe tale verskyn! Hoekom is Java soortgelyk aan C? Omdat C 'n goeie sintaksis gehad het wat almal verstaan ​​het en Java deur hierdie sintaksis geïnspireer is, het die byvoeging van tipe veiligheid, skikkingsgrense-kontrolering, GC, en hulle het ook 'n paar dinge van C verbeter. Hulle het hul eie bygevoeg. Maar hulle was nogal baie geïnspireer, reg? Almal staan ​​op die skouers van die reuse wat voor jou gekom het – dis hoe vordering gemaak word.

Andrew: Soos ek dit verstaan, sal jou taal geheue veilig wees. Het jy al daaraan gedink om iets soos 'n leentoetser van Rust te implementeer? Het jy na hom gekyk, wat dink jy van hom?

Klip: Wel, ek skryf C al vir eeue, met al hierdie malloc en gratis, en bestuur die leeftyd met die hand. Jy weet, 90-95% van handbeheerde leeftyd het dieselfde struktuur. En dit is baie, baie pynlik om dit met die hand te doen. Ek wil graag hê dat die samesteller vir jou bloot vertel wat daar aangaan en wat jy bereik het met jou optrede. Vir sommige dinge, leen checker doen dit uit die boks. En dit moet outomaties inligting vertoon, alles verstaan ​​en my nie eers belas om hierdie begrip aan te bied nie. Dit moet ten minste plaaslike ontsnap-analise doen, en slegs as dit misluk, moet dit tipe-aantekeninge byvoeg wat die leeftyd sal beskryf - en so 'n skema is baie meer kompleks as 'n leentoetser, of inderdaad enige bestaande geheuetoetser. Die keuse tussen “alles is reg” en “ek verstaan ​​niks nie” - nee, daar moet iets beters wees. 
Dus, as iemand wat baie kode in C geskryf het, dink ek dat ondersteuning vir outomatiese leeftydbeheer die belangrikste ding is. Ek is ook keelvol vir hoeveel Java geheue gebruik en die hoofklag is die GC. Wanneer jy geheue in Java toewys, sal jy nie die geheue terugkry wat by die laaste GC-siklus plaaslik was nie. Dit is nie die geval in tale met meer presiese geheuebestuur nie. As jy malloc bel, kry jy dadelik die geheue wat gewoonlik net gebruik is. Gewoonlik doen jy 'n paar tydelike dinge met geheue en gee dit dadelik terug. En dit keer dadelik terug na die malloc-poel, en die volgende malloc-siklus trek dit weer uit. Daarom word werklike geheuegebruik verminder tot die stel lewende voorwerpe op 'n gegewe tyd, plus lekkasies. En as alles nie heeltemal op 'n onbetaamlike manier uitlek nie, beland die meeste van die geheue in die kas en die verwerker, en dit werk vinnig. Maar vereis baie handmatige geheuebestuur met malloc en gratis geroep in die regte volgorde, op die regte plek. Roes kan dit op sy eie behoorlik hanteer, en in baie gevalle selfs beter werkverrigting lewer, aangesien geheueverbruik tot net die huidige berekening vernou word - in teenstelling met wag vir die volgende GC-siklus om geheue vry te maak. Gevolglik het ons 'n baie interessante manier gekry om prestasie te verbeter. En nogal kragtig - ek bedoel, ek het sulke dinge gedoen toe ek data vir fintech verwerk het, en dit het my toegelaat om 'n spoed van ongeveer vyf keer te kry. Dit is 'n redelike groot hupstoot, veral in 'n wêreld waar verwerkers nie vinniger word nie en ons nog wag vir verbeterings.

Prestasie-ingenieur Loopbaan

Andrew: Ek wil ook graag rondvra oor beroepe in die algemeen. Jy het prominent geword met jou JIT-werk by HotSpot en toe na Azul verhuis, wat ook 'n JVM-maatskappy is. Maar ons het reeds meer aan hardeware as sagteware gewerk. En toe het hulle skielik oorgeskakel na Big Data en Machine Learning, en toe na bedrogopsporing. Hoe het dit gebeur? Dit is baie verskillende areas van ontwikkeling.

Klip: Ek programmeer al lank en het daarin geslaag om baie verskillende klasse te neem. En as mense sê: “ag, jy is die een wat JIT vir Java gedoen het!”, is dit altyd snaaks. Maar voor dit het ek aan ’n kloon van PostScript gewerk – die taal wat Apple eens vir sy laserdrukkers gebruik het. En voor dit het ek 'n implementering van die Forth-taal gedoen. Ek dink die algemene tema vir my is gereedskapontwikkeling. My hele lewe lank maak ek gereedskap waarmee ander mense hul cool programme skryf. Maar ek was ook betrokke by die ontwikkeling van bedryfstelsels, drywers, kernvlak-ontfouters, tale vir OS-ontwikkeling, wat triviaal begin het, maar mettertyd al hoe meer kompleks geword het. Maar die hoofonderwerp is steeds die ontwikkeling van gereedskap. ’n Groot deel van my lewe het tussen Azul en Sun verloop, en dit het oor Java gegaan. Maar toe ek by Big Data en Machine Learning ingekom het, het ek my spoggerige hoed weer opgesit en gesê: "O, nou het ons 'n nie-onbelangrike probleem, en daar is baie interessante dinge aan die gang en mense wat dinge doen." Dit is 'n wonderlike ontwikkelingspad om te volg.

Ja, ek is baie lief vir verspreide rekenaars. My eerste werk was as student in C, op 'n advertensieprojek. Dit was verspreide rekenaars op Zilog Z80-skyfies wat data vir analoog OCR versamel het, vervaardig deur 'n regte analoog-ontleder. Dit was 'n koel en heeltemal mal onderwerp. Maar daar was probleme, een of ander deel is nie reg herken nie, so jy moes 'n foto uithaal en dit wys vir 'n persoon wat reeds met hul oë kon lees en rapporteer wat dit sê, en daarom was daar werke met data, en hierdie poste hul eie taal gehad. Daar was 'n backend wat dit alles verwerk het - Z80's wat parallel loop met vt100-terminale wat loop - een per persoon, en daar was 'n parallelle programmeringsmodel op die Z80. Sommige algemene stukkie geheue gedeel deur alle Z80's binne 'n ster opset; Die agtervlak is ook gedeel, en die helfte van die RAM is binne die netwerk gedeel, en 'n ander helfte was privaat of het na iets anders gegaan. 'n Sinvol komplekse parallelverspreide stelsel met gedeelde ... semi-gedeelde geheue. Wanneer was dit ... ek kan nie eers onthou nie, iewers in die middel 80's. Nogal lank gelede. 
Ja, kom ons neem aan dat 30 jaar nogal lank gelede is.Probleme met betrekking tot verspreide rekenaars bestaan ​​al lankal; mense is lankal in oorlog met Beowulf-clusters. Sulke clusters lyk soos... Byvoorbeeld: daar is Ethernet en jou vinnige x86 is aan hierdie Ethernet gekoppel, en nou wil jy vals gedeelde geheue kry, want niemand kon toe verspreide rekenaarkodering doen nie, dit was te moeilik en daarom is daar was vals gedeelde geheue met beskermingsgeheuebladsye op x86, en as jy na hierdie bladsy geskryf het, dan het ons vir ander verwerkers gesê dat as hulle toegang tot dieselfde gedeelde geheue kry, dit van jou af gelaai moet word, en dus iets soos 'n protokol vir ondersteuning kaskoherensie verskyn en sagteware hiervoor. Interessante konsep. Die eintlike probleem was natuurlik iets anders. Dit alles het gewerk, maar jy het vinnig prestasieprobleme gekry, want niemand het die werkverrigtingmodelle op 'n goed genoeg vlak verstaan ​​nie - watter geheuetoegangspatrone was daar, hoe om seker te maak dat die nodusse mekaar nie eindeloos ping nie, ensovoorts.

Waarmee ek vorendag gekom het in H2O is dat dit die ontwikkelaars self is wat verantwoordelik is om te bepaal waar parallelisme versteek is en waar nie. Ek het met 'n koderingsmodel vorendag gekom wat die skryf van hoëprestasiekode maklik en eenvoudig gemaak het. Maar die skryf van stadiglopende kode is moeilik, dit sal sleg lyk. Jy moet ernstig probeer om stadige kode te skryf, jy sal nie-standaardmetodes moet gebruik. Die remkode is met die eerste oogopslag sigbaar. Gevolglik skryf jy gewoonlik kode wat vinnig loop, maar jy moet uitvind wat om te doen in die geval van gedeelde geheue. Dit alles is gekoppel aan groot skikkings en die gedrag daar is soortgelyk aan nie-vlugtige groot skikkings in parallelle Java. Ek bedoel, stel jou voor dat twee drade na 'n parallelle skikking skryf, een van hulle wen, en die ander, dienooreenkomstig, verloor, en jy weet nie watter een is watter nie. As hulle nie wisselvallig is nie, kan die bestelling wees wat jy ook al wil hê - en dit werk baie goed. Mense gee regtig om oor die volgorde van bedrywighede, hulle plaas vlugtige op die regte plekke, en hulle verwag geheueverwante prestasieprobleme op die regte plekke. Andersins sal hulle eenvoudig kode skryf in die vorm van lusse van 1 tot N, waar N 'n paar triljoene is, in die hoop dat alle komplekse gevalle outomaties parallel sal word - en dit werk nie daar nie. Maar in H2O is dit nie Java of Scala nie; jy kan dit as "Java minus minus" beskou as jy wil. Dit is 'n baie duidelike programmeringstyl en is soortgelyk aan die skryf van eenvoudige C- of Java-kode met lusse en skikkings. Maar terselfdertyd kan geheue in teragrepe verwerk word. Ek gebruik steeds H2O. Ek gebruik dit van tyd tot tyd in verskillende projekte – en dit is steeds die vinnigste ding, dosyne kere vinniger as sy mededingers. As jy Big Data met kolomdata doen, is dit baie moeilik om H2O te klop.

Tegniese uitdagings

Andrew: Wat was jou grootste uitdaging in jou hele loopbaan?

Klip: Bespreek ons ​​die tegniese of nie-tegniese deel van die kwessie? Ek sou sê die grootste uitdagings is nie tegniese uitdagings nie. 
Wat tegniese uitdagings betref. Ek het hulle eenvoudig verslaan. Ek weet nie eers wat die grootste een was nie, maar daar was 'n paar baie interessante wat nogal 'n bietjie tyd geneem het, geestelike stryd. Toe ek Son toe is, was ek seker dat ek 'n vinnige samesteller sou maak, en 'n klomp seniors het in reaksie gesê ek sal nooit slaag nie. Maar ek het hierdie pad gevolg, 'n samesteller na die registertoewyser geskryf, en dit was redelik vinnig. Dit was so vinnig soos moderne C1, maar die toewyser was destyds baie stadiger, en agterna was dit 'n groot datastruktuurprobleem. Ek het dit nodig gehad om 'n grafiese registertoewyser te skryf en ek het nie die dilemma tussen kode-ekspressiwiteit en spoed, wat in daardie era bestaan ​​het en baie belangrik was, verstaan ​​nie. Dit het geblyk dat die datastruktuur gewoonlik die kasgrootte op x86's van daardie tyd oorskry, en dus, as ek aanvanklik aanvaar het dat die registertoewyser 5-10 persent van die totale jittertyd sou uitwerk, dan het dit in werklikheid geblyk te wees 50 persent.

Soos die tyd aangegaan het, het die samesteller skoner en doeltreffender geword, in meer gevalle opgehou om verskriklike kode te genereer, en werkverrigting het toenemend begin lyk soos wat 'n C-samesteller produseer. Tensy jy natuurlik 'n kak skryf wat selfs C nie versnel nie . As jy kode soos C skryf, sal jy in meer gevalle prestasie soos C kry. En hoe verder jy gegaan het, hoe meer dikwels het jy kode gekry wat asimptoties met vlak C saamgeval het, die registertoewyser het soos iets voltooi begin lyk... ongeag of jou kode vinnig of stadig loop. Ek het voortgegaan om aan die toewyser te werk om dit beter keuses te maak. Hy het stadiger en stadiger geword, maar hy het beter en beter prestasie gelewer in gevalle waar niemand anders kon klaarkom nie. Ek kon in 'n registertoewyser duik, 'n maand se werk daar begrawe, en skielik sou die hele kode 5% vinniger begin uitvoer. Dit het keer op keer gebeur en die registertoewyser het iets van 'n kunswerk geword - almal was mal daaroor of het dit gehaat, en mense van die akademie het vrae gevra oor die onderwerp "hoekom word alles so gedoen", hoekom nie lynskandering, en wat is die verskil. Die antwoord is steeds dieselfde: 'n toewyser gebaseer op grafiekkleuring plus baie versigtige werk met die bufferkode is gelyk aan 'n wapen van oorwinning, die beste kombinasie wat niemand kan verslaan nie. En dit is 'n taamlik nie-vanselfsprekende ding. Al die ander dinge wat die samesteller daar doen, is redelik goed bestudeerde dinge, hoewel dit ook op kunsvlak gebring is. Ek het altyd dinge gedoen wat veronderstel was om die samesteller in 'n kunswerk te verander. Maar niks hiervan was iets buitengewoons nie – behalwe vir die registertoewyser. Die truuk is om versigtig te wees Sny af onder vrag en, as dit gebeur (ek kan in meer besonderhede verduidelik indien belangstel), beteken dit dat jy meer aggressief kan inlyn, sonder die risiko om oor 'n kinkel in die uitvoeringskedule te val. In daardie dae was daar 'n klomp volskaalse samestellers, gehang met snuisterije en fluitjies, wat registertoewysers gehad het, maar niemand anders kon dit doen nie.

Die probleem is dat as u metodes byvoeg wat onderhewig is aan inlining, verhoging en verhoging van die inlining-area, die stel gebruikte waardes die aantal registers onmiddellik oortref, en u moet dit sny. Die kritieke vlak kom gewoonlik wanneer die toewyser opgee, en een goeie kandidaat vir 'n mors 'n ander werd is, sal jy 'n paar algemeen wilde goed verkoop. Die waarde van inlyn hier is dat jy 'n deel van die bokoste verloor, bokoste vir oproep en spaar, jy kan die waardes binne sien en dit verder kan optimaliseer. Die koste van inlining is dat 'n groot aantal lewendige waardes gevorm word, en as jou registertoewyser meer opbrand as wat nodig is, verloor jy dadelik. Daarom het die meeste toewysers 'n probleem: wanneer inlining 'n sekere lyn oorsteek, begin alles in die wêreld afgekap word en kan produktiwiteit in die toilet afgespoel word. Diegene wat die samesteller implementeer, voeg 'n paar heuristieke by: byvoorbeeld om inlining te stop, begin met 'n voldoende groot grootte, aangesien toekennings alles sal verwoes. Dit is hoe 'n kinkel in die prestasiegrafiek gevorm word - jy inlyn, inlyn, die prestasie groei stadig - en dan boom! – dit val soos 'n vinnige domkrag neer omdat jy te veel gevoer het. Dit is hoe alles gewerk het voor die koms van Java. Java vereis baie meer inlining, so ek moes my toewyser baie meer aggressief maak sodat dit uitvlak eerder as om te crash, en as jy te veel inline, begin dit mors, maar dan kom die “no more mors”-oomblik nog. Dit is 'n interessante waarneming en dit het sommer uit die niet na my gekom, nie voor die hand liggend nie, maar dit het goed vrugte afgewerp. Ek het aggressiewe inlining opgeneem en dit het my na plekke geneem waar Java- en C-uitvoering langs mekaar werk. Hulle is baie naby - ek kan Java-kode skryf wat aansienlik vinniger is as C-kode en sulke dinge, maar gemiddeld, in die groot prentjie van dinge, is hulle min of meer vergelykbaar. Ek dink deel van hierdie meriete is die registertoewyser, wat my in staat stel om so dom as moontlik te inlyn. Ek inline net alles wat ek sien. Die vraag hier is of die toewyser goed werk, of die resultaat intelligent werkende kode is. Dit was 'n groot uitdaging: om dit alles te verstaan ​​en dit te laat werk.

'n Bietjie oor registertoewysing en multi-kerns

Vladimir: Probleme soos registertoewysing lyk na 'n soort ewige, eindelose onderwerp. Ek wonder of daar al ooit 'n idee was wat belowend gelyk het en toe in die praktyk misluk het?

Klip: Sekerlik! Registertoewysing is 'n area waarin jy 'n paar heuristieke probeer vind om 'n NP-volledige probleem op te los. En jy kan nooit 'n perfekte oplossing bereik nie, reg? Dit is eenvoudig onmoontlik. Kyk, voor die tyd samestelling - dit werk ook swak. Die gesprek hier handel oor 'n paar gemiddelde gevalle. Oor tipiese prestasie, so jy kan iets gaan meet wat jy dink goeie tipiese prestasie is – jy werk immers daaraan om dit te verbeter! Registertoewysing is 'n onderwerp wat alles oor prestasie gaan. Sodra jy die eerste prototipe het, dit werk en verf wat nodig is, die uitvoeringswerk begin. Jy moet leer om goed te meet. Hoekom is dit belangrik? As jy duidelike data het, kan jy na verskillende areas kyk en sien: ja, dit het hier gehelp, maar dit is waar alles gebreek het! 'n Paar goeie idees kom op, jy voeg nuwe heuristieke by en skielik begin alles gemiddeld 'n bietjie beter werk. Of dit begin nie. Ek het 'n klomp gevalle gehad waar ons geveg het vir die vyf persent prestasie wat ons ontwikkeling van die vorige toewyser onderskei het. En elke keer lyk dit so: iewers wen jy, iewers verloor jy. As jy goeie werkverrigting-analise-instrumente het, kan jy die verlore idees vind en verstaan ​​hoekom hulle misluk. Miskien is dit die moeite werd om alles te los soos dit is, of dalk 'n meer ernstige benadering tot fyn-instelling te neem, of uit te gaan en iets anders reg te maak. Dit is 'n hele klomp dinge! Ek het hierdie cool hack gemaak, maar ek het ook hierdie een nodig, en hierdie een, en hierdie een - en hul totale kombinasie gee 'n paar verbeterings. En alleenlopers kan misluk. Dit is die aard van prestasiewerk op NP-volledige probleme.

Vladimir: ’n Mens kry die gevoel dat dinge soos om in toewysers te verf ’n probleem is wat reeds opgelos is. Wel, dit is vir jou besluit, te oordeel aan wat jy sê, so is dit dan selfs die moeite werd...

Klip: Dit word nie as sodanig opgelos nie. Dit is jy wat dit in "opgelos" moet omskep. Daar is moeilike probleme en dit moet opgelos word. Sodra dit gedoen is, is dit tyd om aan produktiwiteit te werk. Jy moet hierdie werk dienooreenkomstig benader - doen maatstawwe, versamel maatstawwe, verduidelik situasies wanneer, toe jy teruggerol het na 'n vorige weergawe, jou ou hack weer begin werk het (of andersom, opgehou het). En moenie opgee totdat jy iets bereik het nie. Soos ek reeds gesê het, as daar cool idees is wat nie gewerk het nie, maar op die gebied van toekenning van registers van idees is dit ongeveer eindeloos. Jy kan byvoorbeeld wetenskaplike publikasies lees. Alhoewel nou hierdie gebied baie stadiger begin beweeg het en duideliker geword het as in sy jeug. Daar is egter talle mense wat in hierdie veld werk en al hul idees is die moeite werd om te probeer, hulle wag almal in die vlerke. En jy kan nie sê hoe goed hulle is tensy jy dit probeer nie. Hoe goed integreer hulle met alles anders in jou toewyser, want 'n toewyser doen baie dinge, en sommige idees sal nie in jou spesifieke toewyser werk nie, maar in 'n ander toewyser sal hulle maklik. Die belangrikste manier om te wen vir die toewyser is om die stadige goed buite die hoofpad te trek en dit te dwing om langs die grense van die stadige paaie te verdeel. So as jy 'n GC wil bestuur, neem die stadige pad, deoptimaliseer, gooi 'n uitsondering, al daardie goed - jy weet hierdie dinge is relatief skaars. En hulle is regtig skaars, het ek nagegaan. Jy doen ekstra werk en dit verwyder baie van die beperkings op hierdie stadige paaie, maar dit maak nie regtig saak nie, want hulle is stadig en word selde gereis. Byvoorbeeld, 'n nulwyser - dit gebeur nooit, reg? Jy moet verskeie paaie vir verskillende dinge hê, maar hulle moet nie inmeng met die hoof een nie. 

Vladimir: Wat dink jy van multi-cores, as daar duisende cores gelyktydig is? Is dit 'n nuttige ding?

Klip: Die sukses van die GPU wys dat dit baie nuttig is!

Vladimir: Hulle is nogal gespesialiseerd. Wat van algemene doelverwerkers?

Klip: Wel, dit was Azul se sakemodel. Die antwoord het teruggekom in 'n era toe mense baie van voorspelbare prestasie gehou het. Dit was destyds moeilik om parallelle kode te skryf. Die H2O-koderingsmodel is hoogs skaalbaar, maar dit is nie 'n algemene doelmodel nie. Miskien 'n bietjie meer algemeen as wanneer 'n GPU gebruik word. Praat ons van die kompleksiteit van die ontwikkeling van so iets of die kompleksiteit van die gebruik daarvan? Azul het my byvoorbeeld 'n interessante les geleer, 'n taamlik nie-vanselfsprekende een: klein caches is normaal. 

Die grootste uitdaging in die lewe

Vladimir: Wat van nie-tegniese uitdagings?

Klip: Die grootste uitdaging was om nie... vriendelik en gaaf met mense te wees nie. En gevolglik het ek myself voortdurend in uiters konfliksituasies bevind. Die wat ek geweet het dinge loop verkeerd, maar nie geweet het hoe om vorentoe te gaan met daardie probleme nie en dit nie kon hanteer nie. Baie langtermynprobleme, wat vir dekades duur, het op hierdie manier ontstaan. Die feit dat Java C1- en C2-samestellers het, is 'n direkte gevolg hiervan. Die feit dat daar tien jaar agtereenvolgens geen multi-vlak samestelling in Java was nie, is ook 'n direkte gevolg. Dit is duidelik dat ons so 'n stelsel nodig gehad het, maar dit is nie duidelik waarom dit nie bestaan ​​het nie. Ek het probleme gehad met een ingenieur ... of 'n groep ingenieurs. Eens op 'n tyd, toe ek by Sun begin werk het, was ek... Goed, nie net toe nie, ek het oor die algemeen altyd my eie opinie oor alles. En ek het gedink dit is waar dat jy net hierdie waarheid van jou kan vat en dit reguit kan vertel. Veral omdat ek die meeste van die tyd skokkend reg was. En as jy nie van hierdie benadering hou nie ... veral as jy ooglopend verkeerd is en nonsens doen ... Oor die algemeen kon min mense hierdie vorm van kommunikasie duld. Alhoewel sommige kon, soos ek. Ek het my hele lewe op meritokratiese beginsels gebou. As jy vir my iets verkeerd wys, sal ek dadelik omdraai en sê: jy het twak gesê. Terselfdertyd vra ek natuurlik om verskoning en dit alles, ek sal kennis neem van die meriete, indien enige, en ander korrekte aksies neem. Aan die ander kant is ek skokkend reg oor 'n skokkende groot persentasie van die totale tyd. En dit werk nie baie goed in verhoudings met mense nie. Ek probeer nie gaaf wees nie, maar ek vra die vraag reguit. “Dit sal nooit werk nie, want een, twee en drie.” En hulle was soos: "O!" Daar was ander gevolge wat waarskynlik beter was om te ignoreer: byvoorbeeld dié wat gelei het tot 'n egskeiding van my vrou en tien jaar van depressie daarna.

Uitdaging is 'n stryd met mense, met hul persepsie van wat jy kan of nie kan doen nie, wat belangrik is en wat nie. Daar was baie uitdagings oor koderingstyl. Ek skryf steeds baie kode, en in daardie dae moes ek selfs stadiger ry omdat ek te veel parallelle take gedoen het en dit swak gedoen het, in plaas daarvan om op een te fokus. As ek terugkyk, het ek die helfte van die kode vir die Java JIT-opdrag, die C2-opdrag, geskryf. Die volgende vinnigste kodeerder het die helfte so stadig geskryf, die volgende een helfte so stadig, en dit was 'n eksponensiële afname. Die sewende persoon in hierdie ry was baie, baie stadig - dit gebeur altyd! Ek het baie kode aangeraak. Ek het gekyk wie wat geskryf het, sonder uitsondering, ek het na hul kode gestaar, elkeen van hulle hersien, en steeds aangehou om meer self te skryf as enige van hulle. Hierdie benadering werk nie baie goed met mense nie. Sommige mense hou nie hiervan nie. En wanneer hulle dit nie kan hanteer nie, begin allerhande klagtes. Ek is byvoorbeeld eenkeer aangesê om op te hou kodeer omdat ek te veel kode skryf en dit die span in gevaar stel, en dit het alles vir my soos 'n grap geklink: ou, as die res van die span verdwyn en ek hou aan om kode te skryf, sal jy sal net halwe spanne verloor. Aan die ander kant, as ek aanhou om kode te skryf en jy verloor die helfte van die span, klink dit na baie swak bestuur. Ek het nooit regtig daaraan gedink nie, nooit daaroor gepraat nie, maar dit was steeds iewers in my kop. Die gedagte het in my agterkop rondgedraai: “Krap julle almal?” So, die grootste probleem was ek en my verhoudings met mense. Nou verstaan ​​ek myself baie beter, ek was lank 'n spanleier vir programmeerders, en nou sê ek direk vir mense: jy weet, ek is wie ek is, en jy sal met my moet afreken - is dit reg as ek staan hier? En toe hulle dit begin hanteer, het alles gewerk. Trouens, ek is nie sleg of goed nie, ek het geen slegte bedoelings of selfsugtige aspirasies nie, dit is net my essensie, en ek moet op een of ander manier daarmee saamleef.

Andrew: Net onlangs het almal begin praat oor selfbewustheid vir introverte, en sagte vaardighede in die algemeen. Wat kan jy hieroor sê?

Klip: Ja, dit was die insig en les wat ek uit my egskeiding van my vrou geleer het. Wat ek uit die egskeiding geleer het, was om myself te verstaan. Dit is hoe ek ander mense begin verstaan ​​het. Verstaan ​​hoe hierdie interaksie werk. Dit het die een na die ander tot ontdekkings gelei. Daar was 'n bewustheid van wie ek is en wat ek verteenwoordig. Wat doen ek: óf ek is besig met die taak, óf ek vermy konflik, óf iets anders – en hierdie vlak van selfbewustheid help regtig om myself in beheer te hou. Hierna gaan alles baie makliker. Een ding wat ek nie net in myself nie, maar ook in ander programmeerders ontdek het, is die onvermoë om gedagtes te verbaliseer wanneer jy in 'n toestand van emosionele stres is. Byvoorbeeld, jy sit daar en kodeer, in 'n toestand van vloei, en dan kom hulle na jou aangehardloop en begin in histeries skree dat iets stukkend is en nou sal uiterste maatreëls teen jou getref word. En jy kan nie 'n woord sê nie, want jy is in 'n toestand van emosionele stres. Die verworwe kennis laat jou toe om vir hierdie oomblik voor te berei, dit te oorleef en aan te beweeg na 'n retreatplan, waarna jy iets kan doen. So ja, wanneer jy begin besef hoe dit alles werk, is dit 'n groot lewensveranderende gebeurtenis. 
Ek kon self nie die regte woorde kry nie, maar ek het die volgorde van handelinge onthou. Die punt is dat hierdie reaksie net soveel fisies as verbaal is, en jy het ruimte nodig. Sulke ruimte, in die Zen-sin. Dit is presies wat verduidelik moet word, en stap dan dadelik eenkant toe – stap suiwer fisies weg. Wanneer ek verbaal stilbly, kan ek die situasie emosioneel verwerk. Soos die adrenalien jou brein bereik, jou na veg- of vlugmodus oorskakel, kan jy niks meer sê nie, nee - nou is jy 'n idioot, 'n sweepende ingenieur, nie in staat om 'n ordentlike reaksie of selfs die aanval te stop nie, en die aanvaller is vry weer en weer aan te val. Jy moet eers weer jouself word, beheer herwin, uit die "veg of vlug"-modus kom.

En hiervoor het ons verbale ruimte nodig. Net vrye spasie. As jy enigsins iets sê, dan kan jy presies dit sê en dan regtig "spasie" vir jouself gaan soek: gaan stap in die park, sluit jouself in die stort toe - dit maak nie saak nie. Die belangrikste ding is om tydelik van daardie situasie te ontkoppel. Sodra jy vir ten minste 'n paar sekondes afskakel, die beheer keer terug, begin jy nugter dink. "Goed, ek is nie 'n soort idioot nie, ek doen nie dom dinge nie, ek is 'n redelik nuttige mens." Sodra jy jouself kon oortuig, is dit tyd om aan te beweeg na die volgende stadium: om te verstaan ​​wat gebeur het. Jy is aangeval, die aanval het gekom van waar jy dit nie verwag het nie, dit was 'n oneerlike, gemene hinderlaag. Dit is sleg. Die volgende stap is om te verstaan ​​hoekom die aanvaller dit nodig gehad het. Regtig waarom? Dalk omdat hy self woedend is? Hoekom is hy kwaad? Byvoorbeeld, omdat hy homself opgefok het en nie verantwoordelikheid kan aanvaar nie? Dit is die manier om die hele situasie versigtig te hanteer. Maar dit vereis beweegruimte, verbale ruimte. Die heel eerste stap is om verbale kontak te verbreek. Vermy bespreking met woorde. Kanselleer dit, loop so vinnig as moontlik weg. As dit ’n telefoongesprek is, hang net af – dit is ’n vaardigheid wat ek geleer het deur met my eksvrou te kommunikeer. As die gesprek nêrens goed verloop nie, sê net "totsiens" en hang af. Van die ander kant van die foon: “blah blah blah”, antwoord jy: “yeah, bye!” en hang af. Jy beëindig net die gesprek. Vyf minute later, wanneer die vermoë om sinvol na jou te dink terugkeer, jy bietjie afgekoel het, word dit moontlik om oor alles te dink, wat gebeur het en wat volgende gaan gebeur. En begin om 'n deurdagte reaksie te formuleer, eerder as om net uit emosie te reageer. Vir my was die deurbraak in selfbewustheid juis die feit dat ek in geval van emosionele stres nie kan praat nie. Om uit hierdie toestand te kom, te dink en te beplan hoe om te reageer en vir probleme te vergoed - dit is die regte stappe in die geval wanneer jy nie kan praat nie. Die maklikste manier is om weg te hardloop van die situasie waarin emosionele stres hom manifesteer en bloot op te hou om aan hierdie stres deel te neem. Daarna word jy in staat om te dink, wanneer jy kan dink, word jy in staat om te praat, ensovoorts.

Terloops, in die hof probeer die opponerende prokureur dit aan jou doen - nou is dit duidelik hoekom. Omdat hy die vermoë het om jou tot so 'n toestand te onderdruk dat jy byvoorbeeld nie eers jou naam kan uitspreek nie. In 'n baie werklike sin sal jy nie kan praat nie. As dit met jou gebeur, en as jy weet dat jy jouself in 'n plek sal bevind waar verbale gevegte woed, in 'n plek soos die hof, dan kan jy saam met jou prokureur kom. Die prokureur sal vir jou opstaan ​​en die verbale aanval stop, en sal dit op 'n heeltemal wettige manier doen, en die verlore Zen-ruimte sal na jou terugkeer. Byvoorbeeld, ek moes my familie 'n paar keer bel, die regter was nogal vriendelik hieroor, maar die opponerende prokureur het op my geskree en geskree, ek kon nie eers 'n woord inkry nie. In hierdie gevalle werk die gebruik van 'n bemiddelaar vir my die beste. Die bemiddelaar stop al hierdie druk wat in 'n aaneenlopende stroom op jou uitstort, jy vind die nodige Zen-ruimte, en daarmee kom die vermoë om te praat terug. Dit is 'n hele kennisveld waarin daar baie is om te bestudeer, baie om binne jouself te ontdek, en dit alles verander in hoëvlak strategiese besluite wat vir verskillende mense verskil. Sommige mense het nie die probleme wat hierbo beskryf word nie; mense wat professionele verkoopsmense is, het dit gewoonlik nie. Al hierdie mense wat hul bestaan ​​maak met woorde – bekende sangers, digters, godsdienstige leiers en politici, hulle het altyd iets om te sê. Hulle het nie sulke probleme nie, maar ek het.

Andrew: Dit was ... onverwags. Wonderlik, ons het al baie gepraat en dit is tyd om hierdie onderhoud te beëindig. Ons sal beslis by die konferensie ontmoet en sal hierdie dialoog kan voortsit. Sien jou by Hydra!

Jy kan jou gesprek met Cliff voortsit by die Hydra 2019-konferensie, wat op 11-12 Julie 2019 in St. Hy sal met 'n verslag kom "Die Azul Hardware Transactional Memory-ervaring". Kaartjies kan gekoop word op die amptelike webwerf.

Bron: will.com

Voeg 'n opmerking