Cliff Click â CTO of Cratus (IoT sensors for process improvement), founder and co-founder of several startups (including Rocket Realtime School, Neurensic, and H2O.ai) with several successful exits. Cliff wrote his first compiler at the age of 15 (Pascal for TRS Z-80)! He is best known for his work on C2 in Java (the Sea of Nodes IR). This compiler demonstrated to the world that JIT can produce high-quality code, which became one of the factors in establishing Java as one of the major modern software platforms. Later, Cliff helped Azul Systems build an 864-core mainframe with software written purely in Java that supported GC pauses on a 500-gigabyte heap within 10 milliseconds. Overall, Cliff has worked on all aspects of the JVM.
Â
This blog post is a large interview with Cliff. We will discuss the following topics:
- Transitioning to low-level optimizations
- How to conduct large refactoring
- Cost model
- Learning low-level optimizations
- Practical examples of performance improvement
- Why create your own programming language
- Career of a performance engineer
- Technical challenges
- A bit about register allocation and multithreading
- The biggest challenge in life
The interviewers are:
- Andrey Sataryn from Amazon Web Services. In his career, he has worked on a variety of projects: he tested a NewSQL distributed database at Yandex, a cloud detection system at Kaspersky Lab, a multiplayer game at Mail.ru, and a currency pricing service at Deutsche Bank. He is interested in testing large-scale backend and distributed systems.
- Vladimir Sitnikov from Netcracker. He has been working on the performance and scalability of NetCracker OS â software used by telecom operators to automate network management processes and network equipment. He is passionate about the performance issues of Java and Oracle Database. He is the author of more than a dozen performance improvements in the official PostgreSQL JDBC driver.
Transitioning to low-level optimizations
Andrey: You are a well-known figure in JIT compilation, in Java and performance work in general, right?Â
Cliff: That's right!
Andrey: Let's start with general questions about performance work. What do you think about the choice between high-level and low-level optimizations like working at the CPU level?
Cliff: KĂ«tu gjithçka Ă«shtĂ« e thjeshtĂ«. Kodi mĂ« i shpejtĂ« Ă«shtĂ« ai qĂ« kurrĂ« nuk ekzekutohet. Prandaj, gjithmonĂ« duhet tĂ« filloni nga njĂ« nivel i lartĂ«, tĂ« punoni mbi algoritmet. NjĂ« notacion O mĂ« i mirĂ« do tĂ« tejkalojĂ« njĂ« notacion O mĂ« tĂ« dobĂ«t, pĂ«rveç rastit kur ndĂ«rhyjnĂ« ndonjĂ«herĂ« disa constante mjaft tĂ« mĂ«dha. GjĂ«rat me nivel tĂ« ulĂ«t vijnĂ« tĂ« fundit. Zakonisht, nĂ«se keni optimizuar tĂ« gjithĂ« shtetin tjetĂ«r mjaft mirĂ« dhe ende ka diçka interesante â kjo Ă«shtĂ« niveli i ulĂ«t. Por si tĂ« filloni nga njĂ« nivel i lartĂ«? Si tĂ« dini se keni bĂ«rĂ« mjaft punĂ« nĂ« nivel tĂ« lartĂ«? Epo... nuk ka mĂ«nyra tĂ« gatshme. Duhet tĂ« kuptoni problemin, tĂ« vendosni se çfarĂ« do tĂ« bĂ«ni (pĂ«r tĂ« mos e bĂ«rĂ« hapin e panevojshĂ«m mĂ« vonĂ«) dhe atĂ«herĂ« mund tĂ« hapni profilerin qĂ« mund tĂ« thotĂ« diçka tĂ« dobishme. NĂ« njĂ« moment, ju vetĂ« e kuptoni se keni hequr dorĂ« nga gjĂ«rat e panevojshme dhe Ă«shtĂ« koha tĂ« merret me rregullimin e hollĂ« tĂ« nivelit tĂ« ulĂ«t. Kjo Ă«shtĂ« me siguri njĂ« lloj arti. NjĂ« mori njerĂ«zish bĂ«jnĂ« gjĂ«ra tĂ« panevojshme, por lĂ«vizin aq shpejt saqĂ« nuk kanĂ« kohĂ« tĂ« mendojnĂ« pĂ«r performancĂ«n. Por kjo zgjat derisa çështja tĂ« bĂ«het e rĂ«ndĂ«sishme. Zakonisht, 99% e kohĂ«s askujt nuk i intereson se çfarĂ« po bĂ«j, deri nĂ« momentin kur njĂ« gjĂ« e rĂ«ndĂ«sishme do tĂ« dalĂ« nĂ« rrugĂ«n kritike pĂ«r tĂ« cilĂ«n dikujt i intereson. Dhe kĂ«tu tĂ« gjithĂ« fillojnĂ« tĂ« tĂ« tipojnĂ« pse gjithçka nuk po punonte perfekt qĂ« nĂ« fillim. NĂ« pĂ«rgjithĂ«si, gjithmonĂ« ka diçka pĂ«r tĂ« pĂ«rmirĂ«suar nĂ« performancĂ«. Por 99% e kohĂ«s nuk keni pista! Thjesht po pĂ«rpiqeni tĂ« bĂ«ni diçka tĂ« funksionojĂ« dhe gjatĂ« kĂ«saj i kuptoni ato qĂ« janĂ« thelbĂ«sore. KurrĂ« nuk mund ta dini paraprakisht se ky copĂ« duhet tĂ« bĂ«het perfekt, prandaj, nĂ« thelb, jeni nĂ« mĂ«shirĂ« tĂ« qenit perfekt nĂ« gjithçka. Dhe kjo Ă«shtĂ« e pamundur dhe nuk bĂ«ni ashtu. GjithmonĂ« ka shumĂ« gjĂ«ra pĂ«r t'u riparuar â dhe kjo Ă«shtĂ« krejt normale.
How to conduct large refactoring
Andrey: Si punoni mbi performancën? Kjo është një problem i përgjithshëm. Për shembull, a keni ndonjëherë punuar mbi problemet që lindin nga ndërveprimi i një sërë funksionalitetesh të ekzistuese?
Cliff: UnĂ« pĂ«rpiqem ta shmang kĂ«tĂ«. NĂ«se e di qĂ« performanca do tĂ« bĂ«het njĂ« problem, mendoj pĂ«rpara se tĂ« filloj tĂ« kodoj, veçanĂ«risht pĂ«r strukturat e tĂ« dhĂ«nave. Por shpesh e zbulojmĂ« kĂ«tĂ« shumĂ« mĂ« vonĂ«. Dhe atĂ«herĂ« na duhet tĂ« marrim masa drastike dhe tĂ« bĂ«jmĂ« atĂ« qĂ« e quaj «rishkruaj dhe mbizotĂ«ro»: duhet tĂ« kapim njĂ« copĂ« tĂ« mjaftueshme. NjĂ« pjesĂ« e kodit do tĂ« duhet tĂ« rishkruhet pĂ«r shkak tĂ« problemeve me performancĂ«n ose pĂ«r ndonjĂ« arsye tjetĂ«r. Ădo arsye qĂ« ka tĂ« bĂ«jĂ« me rishkrimin e kodit, ndonjĂ«herĂ« Ă«shtĂ« mĂ« mirĂ« tĂ« rishkruash njĂ« copĂ« mĂ« tĂ« madhe sesa njĂ« copĂ« mĂ« tĂ« vogĂ«l. NĂ« kĂ«tĂ« moment, tĂ« gjithĂ« fillojnĂ« tĂ« tremben: «o Zot, nuk mund tĂ« prekim kaq shumĂ« kod!» Por, nĂ« fakt, ky qasje funksionon shumĂ« mĂ« mirĂ« nĂ« shumicĂ«n e rasteve. Duhet ta kapĂ«sh njĂ« problem tĂ« madh menjĂ«herĂ«, ta pĂ«rshkruash atĂ« rreth njĂ« rrethi tĂ« madh dhe tĂ« thuash: çdo gjĂ« brenda kĂ«tij rrethi, unĂ« do ta rishkruaj. Kufiri Ă«shtĂ« shumĂ« mĂ« i vogĂ«l se ai pĂ«rmbajtje brenda saj, e cila duhet tĂ« zĂ«vendĂ«sohet. Dhe nĂ«se kĂ«tĂ« delimitim kufijsh e bĂ«n punĂ«n brenda perfekte â ke duar tĂ« lira, bĂ«j çfarĂ« dĂ«shiron. Pasi e kupton problemin, procesi i rishkrimit shkon shumĂ« mĂ« lehtĂ«, prandaj kap njĂ« copĂ« tĂ« madhe!
Në të njëjtën kohë, kur bën rishkrimin me një copë të madhe dhe kupton se performanca do të bëhet një problem, mund të fillosh menjëherë të shqetësohesh për të. Normalisht, kjo shndërrohet në gjëra të thjeshta si «mos e kopjo të dhënat, menaxho të dhënat sa më thjeshtë, bëj ato më të vogla». Në rishkrime të mëdha, ka mënyra standarde për të përmirësuar performancën. Dhe ato pothuajse gjithmonë rrotullohen rreth të dhënave.
Cost model
Andrey: Në një nga podkcastet, keni folur për modelet e kostos në kontekstin e performancës. Mund të shpjegoni se çfarë kishte të bëjë me këtë?
Cliff: Sigurisht. UnĂ« kam lindur nĂ« njĂ« epokĂ« kur performanca e procesorit ishte jashtĂ«zakonisht e rĂ«ndĂ«sishme. Dhe kjo epokĂ« po kthehet pĂ«rsĂ«ri â fati nuk Ă«shtĂ« pa ironinĂ« e tij. Kam filluar tĂ« jetoj nĂ« kohĂ«t e makinave tetĂ«bitĂ«she, kompjuteri im i parĂ« punonte me 256 byte. PikĂ«risht byte. Ădo gjĂ« ishte shumĂ« e vogĂ«l. Duhej tĂ« numĂ«roja instrukcionet dhe sapo filluam tĂ« avancohemi lart nĂ« piramidĂ«n e gjuhĂ«ve tĂ« programimit, gjuhĂ«t merrnin pĂ«rsipĂ«r gjithnjĂ« e mĂ« shumĂ«. Kishim Assembler, pastaj Basic, pastaj C, dhe C merrte pĂ«rsipĂ«r punĂ«n me shumĂ« detaje, si pĂ«r shembull menaxhimi i regjistrave dhe zgjedhja e instrukcioneve. Por atje gjithçka ishte mjaft e kuptueshme dhe nĂ«se unĂ« bĂ«ja njĂ« tregues nĂ« njĂ« instancĂ« variable, do tĂ« merrja njĂ« ngarkesĂ«, dhe kostoja e kĂ«tij instrukcioni Ă«shtĂ« e njohur. Hardueri jep njĂ« numĂ«r tĂ« njohur ciklesh mahnitĂ«s, kĂ«shtu qĂ« shpejtĂ«sia e ekzekutimit tĂ« gjĂ«rave tĂ« ndryshme mund tĂ« llogaritet thjesht duke pĂ«rmbledhur tĂ« gjitha instrukcionet qĂ« po planifikon tĂ« ekzekutosh. Ădo krahasim/testim/filim/thirrje/ngarkesĂ«/ruajtje mund tĂ« pĂ«rmblidhet dhe tĂ« thuhet: ja koha e ekzekutimit. Duke u marrĂ« me pĂ«rmirĂ«simin e performancĂ«s, patjetĂ«r qĂ« do t'i shikosh numrat qĂ« pĂ«rkojnĂ« me ciklet e ngrohta tĂ« vogla.Â
Por sapo kalon nĂ« Java, Python dhe gjĂ«ra tĂ« ngjashme, shumĂ« shpejt largohet nga hardueri i nivelit tĂ« ulĂ«t. Cila Ă«shtĂ« kostoja e thirrjes sĂ« getter-it nĂ« Java? NĂ«se JIT nĂ« HotSpot e ka bĂ«rĂ« gjithçka siç duhet , kjo do tĂ« jetĂ« ngarkesĂ«, por, nĂ«se ai nuk e bĂ«ri â kjo do tĂ« jetĂ« njĂ« thirrje funksioni. PasiqĂ« thirrja Ă«shtĂ« nĂ« njĂ« cikĂ«l tĂ« ngrohtĂ«, ajo do tĂ« anulojĂ« tĂ« gjitha optimizimet e tjera nĂ« kĂ«tĂ« cikĂ«l. Prandaj, kostoja reale do tĂ« jetĂ« shumĂ« mĂ« e madhe. Dhe menjĂ«herĂ« humbet aftĂ«sinĂ« pĂ«r tĂ« parĂ« njĂ« copĂ« kod dhe tĂ« kuptosh se sa vlen ta ekzekutosh atĂ« nĂ« terma tĂ« frekuencĂ«s sĂ« procesorit, memories pĂ«rdorur dhe caches. TĂ« gjitha kĂ«to bĂ«hen interesante vetĂ«m nĂ«se do tĂ« futesh thellĂ« nĂ« performancĂ«.
Tani jemi nĂ« njĂ« situatĂ« ku shpejtĂ«sitĂ« e procesorĂ«ve nuk kanĂ« pasur rritje pĂ«r mĂ« shumĂ« se njĂ« dekadĂ«. Koha e vjetĂ«r po kthehet! Nuk mund tĂ« shqetĂ«soheni mĂ« pĂ«r performancĂ«n e mirĂ« tĂ« njĂ« njĂ«sie. Por, nĂ«se papritmas merret me llogaritjet paralele â Ă«shtĂ« gjithmonĂ« e komplikuar, tĂ« gjithĂ« tĂ« shikojnĂ« si James Bond. ShpejtĂ«sitĂ« dhjetĂ«fishohet zakonisht ndodhin nĂ« ato vende ku dikush ka humbur diçka. Paraleliteti kĂ«rkon shumĂ« punĂ«. PĂ«r tĂ« arritur atĂ« dhjetĂ«fishim tĂ« shpejtĂ«sisĂ«, duhet tĂ« kuptohet modeli i kostos. ĂfarĂ« dhe sa kushton. Dhe pĂ«r kĂ«tĂ«, duhet tĂ« kuptohet se si gjuha pĂ«rputhet me harduerin nĂ« dispozita.
Martin Thompson ka gjetur njĂ« fjalĂ« tĂ« shkĂ«lqyer pĂ«r blogun e tij ! Duhet tĂ« kuptohet se çfarĂ« do tĂ« bĂ«jĂ« hardueri, si do ta bĂ«jĂ« dhe pse e bĂ«n atĂ« qĂ« bĂ«n. Duke e pĂ«rdorur kĂ«tĂ«, Ă«shtĂ« mjaft e lehtĂ« tĂ« fillosh tĂ« numĂ«rosh instruktionet dhe tĂ« zbulohet se ku po shkon koha e ekzekutimit. NĂ«se nuk ke pĂ«rgatitjen pĂ«rkatĂ«se, thjesht je duke kĂ«rkuar njĂ« mace tĂ« zezĂ« nĂ« njĂ« dhomĂ« tĂ« errĂ«t. UnĂ« vazhdimisht shoh njerĂ«z qĂ« optimizojnĂ« performancĂ«n, ndonĂ«se ata nuk kanĂ« as njĂ« ide se çfarĂ« po bĂ«jnĂ«. Ata kanĂ« shumĂ« vuajtje dhe nuk po e arrijnĂ« ndonjĂ«herĂ« qĂ«llimin. Kur unĂ« marr tĂ« njĂ«jtin copĂ« kod, vendos atje disa hacks tĂ« vogla dhe arrij katĂ«rfishim ose dhjetĂ«fishim tĂ« shpejtĂ«sisĂ«, ata thonĂ«: mirĂ«, kjo nuk Ă«shtĂ« e ndershme, ne e dinim se ishe mĂ« i mirĂ«. Maçkullisht. ĂfarĂ« po flas⊠modeli i kostos Ă«shtĂ« pĂ«r atĂ« qĂ« kodin e shkruan dhe si funksionon nĂ« mes njĂ« pamjeje tĂ« pĂ«rgjithshme.
Andrey: Dhe si të mbash një vëllim të tillë në mendje? Kjo arrihet përmes shumë përvojës, apo? Ku sigurohet një përvojë e tillë?
Cliff: Mirë, përvoja ime ka ardhur në një mënyrë jo të lehtë. Kam programuar në Assembler në ato kohë kur mund të kuptohej çdo instruktion i veçantë. Kjo duket e çuditshme, por që nga ajo kohë kam një grup instruktionesh Z80 që më kanë mbetur gjithmonë në mendje. Nuk kujtoj emrat e njerëzve pas një minute të bisedës, por kujtoj kodin e shkruar 40 vjet më parë. Qesharake, kjo duket si sindromi i "».
Learning low-level optimizations
Andrey: A ka ndonjë mënyrë më të thjeshtë për të hyrë në këtë fushë?
Cliff: Po, dhe jo. Hardueri për të cilin të gjithë ne përdorim, gjatë kësaj kohe nuk ka ndryshuar shumë. Të gjithë përdorin x86, përveç smartphone-ve që përdorin Arm. Nëse nuk merresh me ndonjë embedim të fortë, ke të njëjtën gjë. Mirë, më tutje. Instruksionet gjithashtu nuk kanë ndryshuar për shekuj. Duhet të shkosh dhe të shkruash diçka në Assembler. Pak, por mjaftueshëm për të filluar të kuptohet. Ju buzëqeshni, por unë flas gjithmonë seriozisht. Duhet të kuptosh përputhjen mes gjuhës dhe harduerit. Pas kësaj, duhet të shkosh, të shkruash pak dhe të bësh një kompilator të vogël për një gjuhë të vogël. "I vogël" do të thotë se duhet ta bësh atë brenda një kohë të arsyeshme. Ai mund të jetë shumë i thjeshtë, por duhet të gjenerojë instruksione. Akti i gjenerimit të instruksionit do të lejojë të kuptohet modeli i koston për urën mes kodit të nivelit të lartë, në të cilin të gjithë shkruajnë, dhe kodit të makinës, i cili ekzekutohet në harduer. Kjo përputhje do të thellohet në mendjet e njerëzve në momentin e shkruarjes së kompilatorit. Edhe të kompilatorit më të thjeshtë. Pas kësaj, mund të fillosh të shikosh Java dhe se sa e thellë është hendeku semantik dhe për të ndërtuar ura mbi të, është shumë më e komplikuar. Në Java është shumë më e vështirë të kuptosh nëse ura jonë është e mirë apo e keqe, çfarë do ta bëjë atë të shembet dhe çfarë jo. Por të duhet një pikë nisëse, kur shikon kodin dhe kupton: "Ah, ky getter duhet të linjëzohet çdo herë". Më pas del se ndonjëherë ndodh, përveç rasteve kur metodi bëhet shumë i madh dhe JIT fillon të linjëzojë gjithçka. Performanca e këtyre vendeve mund të parashikohet menjëherë. Zakonisht gettaret punojnë mirë, por pastaj shikon ciklet e mëdha të nxehta dhe kupton se ka thirrje funksionesh që nuk e dinë se çfarë bëjnë. Kjo është problemi me përdorimin universalisht të gettareve, arsyeja pse ato nuk linjëzohen - nuk është e qartë se a është ky një getter. Nëse ke një bazë të kodit shumë të vogël, mund ta mbash mend atë dhe më pas të thuash: ja, ky është një getter, dhe ky është një setter. Në një bazë të madhe të kodit, çdo funksion jeton historinë e vet, të cilën askush, në përgjithësi, nuk e di. Profili tregon se kemi humbur 24% të kohës në ndonjë cikël dhe për të kuptuar se çfarë bën ky cikël, duhet të shikosh çdo funksion brenda. Nuk është e mundur të kuptohet kjo, pa studiuar funksionin, dhe kjo e ngadalëson seriozisht procesin e kuptimit. Prandaj unë nuk përdor geterë e seterë, unë kam arritur në një nivel të ri!
Si te pyet se ku ta gjej modelin e kostos? Po, mund të lexosh diçka, sigurisht... Por mendoj se mënyra më e mirë është të veprosh. Të krijosh një kompilator të vogël dhe kjo do të jetë mënyra më e mirë për ta kuptuar modelin e kostos dhe ta vendosësh atë në kokën e tua. Një kompilator i vogël që do të ishte i dobishëm për programimin e mikrovalës - kjo është një detyrë për fillestarët. E di që nëse tashmë ke aftësi programimi, duhet të mjaftojnë. Të gjitha këto gjëra si shfrytëzimi i një vargu që do të jetë ndonjë shprehje algjebrike, nxjerrja e udhëzimeve për operacionet matematikore në rendin e duhur, marrja e vlerave të sakta nga regjistrat - gjithçka bëhet lehtë. Dhe sa herë që bën këtë, do të mbetet në mendje. Mendoj se të gjithë e dinë se çfarë bën një kompilator. Dhe kjo do të sjellë kuptimin e modelit të kostos.
Practical examples of performance improvement
Andrey: ĂfarĂ« tjetĂ«r duhet tĂ« vĂ«mĂ« re gjatĂ« punĂ«s mbi performancĂ«n?
Cliff: Strukturat e të dhënave. Për të vërtetë, unë nuk kam mbajtur këto lekcioni prej një kohe të gjatë... . Ishte argëtuese, por kërkonte shumë përpjekje, dhe unë kam një jetë gjithashtu! Mirë, kështu që, në njërën nga mësimet më të mëdha dhe interesante, "Ku shkon performanca juaj", iu dhashë studentëve një shembull: dy e gjysmë gigabajt të dhënash fintech lexoheshin nga një skedar CSV dhe më pas duhej të llogaritej numri i produkteve të shitura. Të dhëna të rregullta tregtare. Paketa UDP, të transformuara në format tekstual, që nga vitet '70. Chicago Mercantile Exchange - gjëra si nafta, misri, soja dhe të ngjashme. Duhej të llogaritnim këto produkte, numrin e transaksioneve, volumin mesatar të qarkullimit të fondeve dhe mallrave, etj. Kjo është matematikë tregtare mjaft e thjeshtë: gjej kodin e produktit (këto janë 1-2 simbole në një tabelë hesh), merr shumën, shto në një nga grupe të transaksioneve, shto volumet, shto kostot dhe disa gjëra të tjera. Matematikë shumë e thjeshtë. Implementimi i lodhshëm ishte mjaft i drejtpërdrejtë: gjithçka ndodhte në një skedar, lexoja skedarin dhe lëvizja përmes tij, duke ndarë regjistrat në vargje Java, duke kërkuar në to gjërat e nevojshme dhe duke i shtuar sipas matematikës së përshkruar më sipër. Dhe kjo funksiononte me një shpejtësi të vogël.
Me kĂ«tĂ« qasje, gjithçka Ă«shtĂ« e qartĂ« se çfarĂ« po ndodh, dhe llogaritĂ« paralele kĂ«tu nuk ndihmojnĂ«, e drejta? Doli qĂ« rritja pesĂ«fish e performancĂ«s mund tĂ« arrihet thjesht duke zgjedhur struktura tĂ« duhura tĂ« tĂ« dhĂ«nave. Dhe kjo e befason edhe programuesit mĂ« tĂ« pĂ«rvojshĂ«m! NĂ« rastin tim konkret, fokusi ishte qĂ« nuk duhet tĂ« bĂ«sh ndarje memorie nĂ« ciklin e nxehtĂ«. Po, kjo nuk Ă«shtĂ« e gjithĂ« e vĂ«rteta, por nĂ« pĂ«rgjithĂ«si - nuk duhet tĂ« ndash 'nĂ« çdo X', kur X Ă«shtĂ« mjaft i madh. Kur X Ă«shtĂ« dy e gjysmĂ« gigabajt, nuk duhet tĂ« ndash asgjĂ« 'nĂ« çdo letĂ«r', ose 'nĂ« çdo rresht', ose 'nĂ« çdo fushĂ«', asgjĂ« tĂ« tillĂ«. PikĂ«risht kĂ«tu shpenzohet koha. Si funksionon kjo nĂ« tĂ« vĂ«rtetĂ«? Imagjinoni se unĂ« bĂ«j njĂ« thirrje String.split() ose BufferedReader.readLine(). Readline bĂ«n njĂ« varg nga njĂ« grup bajtokĂ«sh qĂ« vijnĂ« pĂ«rmes rrjetit, njĂ« herĂ« pĂ«r çdo varg, pĂ«r secilin nga qindra miliona vargjeve. UnĂ« e marr kĂ«tĂ« varg, e analizoj dhe e hedh. Pse e hedh - mirĂ«, unĂ« e kam pĂ«rpunuar atĂ«, mbaroi. Pra, pĂ«r çdo bajt qĂ« lexoj nga kĂ«to 2.7G, do tĂ« shkruhen dy simbole nĂ« varg, dmth tashmĂ« 5.4G, dhe ato mĂ« tej nuk mĂ« duhen pĂ«r asgjĂ«, ndaj hidhen. NĂ«se shikojmĂ« kapacitetin e memorjes, ne ngarkojmĂ« 2.7G, qĂ« kalojnĂ« pĂ«rmes memories dhe busit tĂ« memories nĂ« procesor, dhe mĂ« pas dy herĂ« mĂ« shumĂ« dĂ«rgohen nĂ« vargun qĂ« Ă«shtĂ« nĂ« memorje, dhe e gjithĂ« kjo pĂ«rplaset kur krijohet çdo varg i ri. Por unĂ« duhet ta lexoj atĂ«, hardueri e lexon atĂ«, edhe nĂ«se pastaj gjithçka do tĂ« pĂ«rpunohet. Dhe duhet ta shkruaj, sepse kam krijuar njĂ« varg dhe caches janĂ« mbushur â cache nuk mund ta akomodojĂ« 2.7G. Pra, pĂ«r çdo bajt tĂ« lexuar lexoj edhe dy bajte shtesĂ« dhe shkruaj dy bajte shtesĂ«, dhe nĂ« fund ata kanĂ« njĂ« raport 4:1 â nĂ« kĂ«tĂ« raport ne harxhojmĂ« pa efekt kapacitetin e memories. Dhe mĂ« pas del se nĂ«se bĂ«j String.split() â e bĂ«j kĂ«tĂ« shumĂ« herĂ«, brenda mund tĂ« kenĂ« edhe 6-7 fusha tĂ« tjera. Prandaj, kodi klasik pĂ«r leximin e CSV duke pasuar analizĂ«n e vargjeve çon nĂ« humbje tĂ« kapacitetit tĂ« memories nĂ« rreth 14:1 nĂ« krahasim me atĂ« qĂ« do tĂ« dĂ«shironit realisht tĂ« kishit. NĂ«se heqim kĂ«to ndarje, atĂ«herĂ« mund tĂ« arrijmĂ« njĂ« pĂ«rshpejtim pesĂ«fish.
Dhe kjo nuk Ă«shtĂ« ndonjĂ« gjĂ« tejet e komplikuar. NĂ«se e shihni kodin nga kĂ«ndvĂ«shtrimi i duhur, gjithçka bĂ«het mjaft e thjeshtĂ«, sapo ta kuptoni esencialin e problemit. Nuk duhet aspak tĂ« ndaloni dhĂ«nien e memories: problemi Ă«shtĂ« se po i jepni diçka dhe ajo vdes menjĂ«herĂ«, duke shpenzuar njĂ« burim tĂ« rĂ«ndĂ«sishĂ«m, i cili nĂ« kĂ«tĂ« rast Ă«shtĂ« kapaciteti i memories. Dhe e gjithĂ« kjo rezulton nĂ« njĂ« rĂ«nie tĂ« performancĂ«s. NĂ« x86 zakonisht duhet tĂ« digjni me akt tĂ« procesorit, ndĂ«rsa kĂ«tu keni djegur tĂ« gjithĂ« memories pĂ«rpara sĂ« pritur. Zgjidhja Ă«shtĂ« tĂ« reduktoni numrin e alokimeve.Â
NjĂ« tjetĂ«r pjesĂ« e problemit Ă«shtĂ« se, nĂ«se e aktivizoni profiler-in kur Ă«shtĂ« pĂ«rfunduar banda e memories, pikĂ«risht nĂ« momentin kur ndodh, zakonisht prisni qĂ« cache tĂ« rikthehet, sepse Ă«shtĂ« plot me plehra qĂ« sapo keni prodhuar, me tĂ« gjitha kĂ«to rreshta. Prandaj, çdo operacion load ose store bĂ«het i ngadalshĂ«m, sepse ato sjellin humbje nĂ« cache â e gjithĂ« cache ka ulet ngadalĂ«, duke pritur qĂ« plehrat tĂ« dalin. Prandaj, profiler-i do tĂ« tregojĂ« vetĂ«m njĂ« zhurmĂ« tĂ« ngrohtĂ« rastĂ«sore, tĂ« shtrirĂ« pĂ«rgjatĂ« gjithçkaje â nuk do tĂ« ketĂ« ndonjĂ« urdhĂ«r tĂ« veçantĂ« tĂ« nxehtĂ« ose vend nĂ« kod. VetĂ«m zhurmĂ«. Dhe nĂ«se shihni ciklet GC, ato do tĂ« jenĂ« tĂ« gjitha pĂ«r Generacionin e Ri dhe shumĂ« tĂ« shpejta â mikrosekuonda ose milisekonda maksimumi. Sepse e gjithĂ« kjo memory vdes menjĂ«herĂ«. Ju alokoni miliarda gigabajt, dhe ai i shkurton, dhe i shkurton, dhe pĂ«rsĂ«ri i shkurton. E gjithĂ« kjo ndodh shumĂ« shpejt. Pra, ka cikle tĂ« lira GC, zhurmĂ« tĂ« ngrohtĂ« pĂ«rgjatĂ« gjithçkaje, por ne duam tĂ« arrijmĂ« njĂ« pĂ«rshpejtim 5-fish. NĂ« kĂ«tĂ« moment diçka duhet tĂ« lidhet nĂ« mendjen tuaj dhe tĂ« dĂ«gjojĂ«: âpse kĂ«shtu?!â. Teqja e rripit tĂ« memories nuk shfaqet nĂ« debugger-in klasik, duhet tĂ« aktivizoni debugger-in e shifruesve tĂ« harduerit e tĂ« performance dhe ta shihni atĂ« vetĂ« dhe drejtpĂ«rdrejt. Ndryshe, mund tĂ« dyshoni pĂ«r kĂ«tĂ« nga kĂ«to tri simptoma. Simptoma e tretĂ« Ă«shtĂ« kur shihni atĂ« qĂ« alokoni, pyesni profiler-in, dhe ai pĂ«rgjigjet: âJu keni bĂ«rĂ« miliardĂ« rreshta, por GC ka vepruar falasâ. Sapo ndodh kjo, e kuptoni se keni krijuar shumĂ« objekte dhe keni djegur tĂ« gjithĂ« shiritin e memories. Ka njĂ« mĂ«nyrĂ« pĂ«r ta zbuluar kĂ«tĂ«, por nuk Ă«shtĂ« e qartĂ«.Â
Problemi Ă«shtĂ« nĂ« strukturĂ«n e tĂ« dhĂ«nave: struktura e hollĂ«, qĂ« qĂ«ndron pas gjithçkaje, Ă«shtĂ« shumĂ« e madhe, Ă«shtĂ« 2.7G nĂ« disk, prandaj tĂ« bĂ«sh njĂ« kopje tĂ« kĂ«saj gjĂ«je Ă«shtĂ« shumĂ« e padĂ«shirueshme â dĂ«shiron ta ngarkosh direkt nga bufri i bytes nĂ« regjistrat, nĂ« mĂ«nyrĂ« qĂ« tĂ« mos lexosh-shkruash nĂ« varg çdo herĂ« pesĂ« herĂ«. FatkeqĂ«sisht, Java, nĂ« mĂ«nyrĂ« tĂ« paracaktuar, nuk tĂ« jep njĂ« bibliotekĂ« tĂ« tillĂ« si pjesĂ« e JDK. Por kjo Ă«shtĂ« thjesht, apo jo? NĂ« thelb, janĂ« 5-10 rreshta kodi qĂ« do tĂ« shkojnĂ« pĂ«r implementimin e njĂ« ngarkuesi tĂ« vet, i cili pĂ«rsĂ«rit sjelljen e klasĂ«s sĂ« vargjeve, duke qenĂ« njĂ« mbĂ«shtjellĂ«s mbi bufret e bytes nĂ« nivelin e poshtĂ«m. Si rezultat, rezulton se punon pothuajse si me vargje, por nĂ« tĂ« vĂ«rtetĂ«, aty lĂ«vizin treguesit nĂ« bufĂ«r, dhe bytes e papĂ«rpunuara nuk kopjohen askund, dhe kĂ«shtu ripĂ«rdoren tĂ« njĂ«jtat bufe, herĂ« pas here, dhe sistemi operacional Ă«shtĂ« i lumtur tĂ« marrĂ« pĂ«rsipĂ«r gjĂ«rat pĂ«r tĂ« cilat Ă«shtĂ« e destinuar, siç Ă«shtĂ« dyfishimi i padukshĂ«m i kĂ«tyre bufreve tĂ« bytes, ndĂ«rsa ti vetĂ« nuk merresh mĂ« me njĂ« rrjedhĂ« tĂ« pafund tĂ« tĂ« dhĂ«nave tĂ« panevojshme. PĂ«r rastin, ju e kuptoni, gjatĂ« punĂ«s me GC garanton qĂ« çdo ndarje e memories nuk do tĂ« shihet nga procesori pas ciklit tĂ« fundit tĂ« GC? Prandaj, e gjithĂ« kjo nuk mund tĂ« jetĂ« nĂ« cache, dhe mĂ« pas ndodh njĂ« humbje e garantuar 100%. GjatĂ« punĂ«s me njĂ« tregues, nĂ« x86, tĂ« lexosh njĂ« regjistĂ«r nga memoria merr 1-2 cikle, dhe sa herĂ« qĂ« ndodh kjo, ti paguan, paguan, paguan, sepse e gjithĂ« memoria Ă«shtĂ« â dhe kjo Ă«shtĂ« kostumi i ndarjes sĂ« memories. Kostumi i vĂ«rtetĂ«.
Me thënë, strukturat e të dhënave janë ato që është më e vështirë të ndryshosh. Dhe sapo kuptoni se keni zgjedhur strukturën e gabuar të të dhënave që më vonë do të dëmtojë performancën, zakonisht kërkohet një punë e madhe për t'u rikthyer, por nëse nuk e bëni këtë, situata do të përkeqësohet. Së pari, duhet të mendoni për strukturat e të dhënave, kjo është e rëndësishme. Kostoja kryesore këtu bie mbi strukturat e mëdha të të dhënave, të cilat fillojnë të përdoren në stilin 'unë kopjova strukturën e të dhënave X në strukturën e të dhënave Y, sepse Y më pëlqen më shumë në formë'. Por operacioni i kopjimit (i cili duket i lirë) në të vërtetë shpenzon hapësirën në kujtesë dhe këtu është ku humbet gjithçka në kohë ekzekutimi. Nëse kam një varg të madh me JSON dhe dua ta shndërroj atë në një pemë DOM të strukturuar nga POJO ose diçka e tillë, operacioni i analizimit të këtij vargu dhe ndërtimi të POJO dhe më pas një shfrytëzim të ri të POJO në vazhdim do të kthehen në një kosto shtesë - një gjë e shtrenjtë. Me përjashtim të rastit kur do të lëvizni përmes POJO shumë më shpesh sesa përmes vargut. Në vend të kësaj, mund të provoni të deshifroni vargun dhe të nxirrni vetëm atë që ju nevojitet, pa e shndërruar në asnjë POJO. Nëse e gjithë kjo ndodh në një rrugë, nga e cila kërkohet performanca maksimale, asnjë POJO - duhet të hidhni diku drejt vargut.
Why create your own programming language
Andrey: Ju thatĂ« se pĂ«r tĂ« kuptuar modelin e kostos, duhet tĂ« shkruani njĂ« gjuhĂ« tĂ« vogĂ«lâŠ
Cliff: Jo njĂ« gjuhĂ«, por njĂ« kompilator. Gjuha dhe kompileri janĂ« gjĂ«ra tĂ« ndryshme. Dallimi mĂ« i rĂ«ndĂ«sishĂ«m Ă«shtĂ« nĂ« mendjen tuaj.Â
Andrey: Përsa i përket, sa di unë, po eksperimentoni me krijimin e gjuhëve tuaja. Pse?
Cliff: Sepse mundem! Jam gjysmĂ« nĂ« pension, kĂ«shtu qĂ« kjo Ă«shtĂ« hobiu im. Kam realizuar gjuhĂ« tĂ« huaja gjatĂ« gjithĂ« jetĂ«s sime. Kam punuar shumĂ« edhe mbi stilin e kodimit. Po ashtu, shoh probleme nĂ« gjuhĂ«t e tjera. Shoh se ka mĂ«nyra mĂ« tĂ« mira pĂ«r tĂ« bĂ«rĂ« gjĂ«ra tĂ« zakonshme. Dhe do t'i shfrytĂ«zoja ato. Thjesht jam i lodhur nga problemet nĂ« vetvete, nĂ« Java, nĂ« Python, nĂ« çdo gjuhĂ« tjetĂ«r. Tani po shkruaj nĂ« React Native, JavaScript dhe Elm si njĂ« hob, i cili nuk ka tĂ« bĂ«jĂ« me pensionin, por me punĂ« aktive. Po ashtu shkruaj edhe nĂ« Python dhe ndoshta do tĂ« vazhdoj tĂ« punoj mbi mĂ«simin e makinerive pĂ«r backend-et Java. Ka shumĂ« gjuhĂ« tĂ« njohura dhe secila ka veçoritĂ« e saj interesante. Ădo njĂ«ra Ă«shtĂ« e mirĂ« pĂ«r diçka dhe mund tĂ« provosh tĂ« bashkosh tĂ« gjitha kĂ«to karakteristika. Pra, merrem me studimin e gjĂ«rave interesante pĂ«r mua, sjelljes sĂ« gjuhĂ«s, pĂ«rpiqem tĂ« shpik njĂ« semantikĂ« tĂ« arsyeshme. Deri tani po arrij! Aktualisht po luftoj me semantikĂ«n e memories, sepse dĂ«shiroj ta kem si nĂ« C dhe Java, dhe tĂ« kem njĂ« model tĂ« fortĂ« memorje dhe semantikĂ« pĂ«r ngarkesat dhe dyqanet. Pas kĂ«saj, tĂ« kem automatikisht nxjerrjen e tipave si nĂ« Haskell. KĂ«shtu, po pĂ«rpiqem tĂ« pĂ«rziej nxjerrjen e tipave tĂ« ngjashme me Haskell me njĂ« memorie qĂ« punon si nĂ« C dhe Java. KĂ«tĂ« e kam bĂ«rĂ« pĂ«r 2-3 muajt e fundit, pĂ«r shembull.
Andrey: Nëse po ndërtoni një gjuhë që merr aspektet më të mira nga gjuhë të tjera, keni menduar ndonjëherë se dikush do të bëjë të kundërtën: do të marrë idetë tuaja dhe do t'i përdorë për vete?
Cliff: Ky Ă«shtĂ« mĂ«nyra se si lindin gjuhĂ«t e reja! Pse Java Ă«shtĂ« e ngjashme me C? Sepse C kishte njĂ« sintaksĂ« tĂ« mirĂ«, qĂ« tĂ« gjithĂ« e kuptonin dhe Java u frymĂ«zua nga kjo sintaksĂ«, duke shtuar aty sigurinĂ« e tipit, kontrollin e kufijve tĂ« masivave, GC, dhe pĂ«rmirĂ«suan disa gjĂ«ra nga C. Ata shtuan tĂ« tyret. Por ata ishin shumĂ« tĂ« frymĂ«zuar, apo jo? TĂ« gjithĂ« qĂ«ndrojnĂ« mbi supet e gjigantĂ«ve qĂ« ishin para teje â kĂ«shtu bĂ«het progresi.
Andrey: Sa kuptoj, gjuha juaj do të jetë e sigurt në lidhje me përdorimin e memories. Keni menduar të realizoni diçka si borrow checker nga Rust? E keni parë atë, si ju duket?
Cliff: Kam, unĂ« kam shkruar nĂ« C pĂ«r njĂ« kohĂ« tĂ« gjatĂ«, me gjithĂ« kĂ«to malloc dhe free, dhe menaxhoj manualisht kohĂ«zgjatjen. E dini, 90-95% e menaxhimit manual tĂ« kohĂ«zgjatjes ka njĂ« strukturĂ« tĂ« njĂ«jtĂ«. Dhe Ă«shtĂ« shumĂ«, shumĂ« e dhimbshme tĂ« merresh me kĂ«tĂ« manualisht. Do tĂ« doja qĂ« kompajleri thjesht tĂ« tregonte se çfarĂ« ndodh dhe çfarĂ« arrin me veprimet e tua. PĂ«r disa gjĂ«ra, borrow checker e bĂ«n kĂ«tĂ« automatikisht. Dhe ai duhet gjithashtu tĂ« nxjerrĂ« automatikisht informacione, tĂ« kuptojĂ« gjithçka dhe madje tĂ« mos mĂ« ngarkojĂ« me detyrĂ«n e shpjegimit tĂ« atij kuptimi. Ai duhet tĂ« bĂ«jĂ« tĂ« paktĂ«n njĂ« analizĂ« lokale tĂ« arratisjes, dhe vetĂ«m nĂ«se nuk ia del, atĂ«herĂ« duhet tĂ« shtosh annotationet e tipeve qĂ« do tĂ« pĂ«rshkruanin kohĂ«zgjatjen â dhe njĂ« skemĂ« e tillĂ« Ă«shtĂ« shumĂ« mĂ« e komplikuar se borrow checker, ose ndonjĂ« checker tĂ« ekzistueshĂ«m tĂ« memories. Zgjedhja mes 'gjithçka Ă«shtĂ« nĂ« rregull' dhe 'nuk kuptova asgjĂ«' â jo, duhet tĂ« ketĂ« diçka mĂ« tĂ« mirĂ«.Â
Prandaj, si njĂ« person qĂ« ka shkruar shumĂ« kod nĂ« C, mendoj se mbĂ«shtetja pĂ«r menaxhimin automatik tĂ« jetĂ«s sĂ« resurseve Ă«shtĂ« gjĂ«ja mĂ« e rĂ«ndĂ«sishme. Gjithashtu, mĂ« ka irrituar sa shumĂ« Java pĂ«rdor memorie, dhe ankesa kryesore Ă«shtĂ« nĂ« GC. Kur alokoni memorie nĂ« Java, memoria qĂ« ka qenĂ« lokale nĂ« ciklin e fundit tĂ« GC nuk kthehet. NĂ« gjuhĂ«t me menaxhim mĂ« tĂ« saktĂ« tĂ« memorjes, kjo nuk ndodh. NĂ«se thĂ«rrisni malloc, merrni menjĂ«herĂ« memorie qĂ« zakonisht sapo Ă«shtĂ« pĂ«rdorur. Zakonisht, ju bĂ«ni disa gjĂ«ra tĂ« pĂ«rkohshme me memorien dhe menjĂ«herĂ« e ktheni atĂ«. Dhe ajo kthehet menjĂ«herĂ« pĂ«rsĂ«ri nĂ« pool-in e malloc, dhe cikli i ardhshĂ«m i malloc e nxjerr atĂ« jashtĂ« pĂ«rsĂ«ri. Prandaj, pĂ«rdorimi i vĂ«rtetĂ« i memorjes ulĂ«t nĂ« setin e objekteve tĂ« gjallĂ« nĂ« njĂ« moment tĂ« caktuar, plus rrjedhjet. Dhe nĂ«se nuk keni rrjedhje nĂ« njĂ« mĂ«nyrĂ« krejt tĂ« papĂ«rshtatshme, pjesa mĂ« e madhe e memorjes mbetet nĂ« cache dhe procesorĂ«, dhe kjo punon shpejt. Por kĂ«rkon shumĂ« menaxhim manual tĂ« memorjes me malloc dhe free, tĂ« thĂ«rritura nĂ« rendin e duhur, nĂ« vendin e duhur. Rust mund ta menaxhojĂ« kĂ«tĂ« vetĂ« siç duhet dhe nĂ« shumĂ« raste ofron madje mĂ« shumĂ« performancĂ«, pasi pĂ«rdorimi i memorjes zvogĂ«lohet vetĂ«m nĂ« llogaritjet aktuale â nĂ« vend tĂ« pritjes pĂ«r ciklin e ardhshĂ«m tĂ« GC, i cili do tĂ« lirojĂ« memorien. NĂ« fund, arritĂ«m njĂ« mĂ«nyrĂ« shumĂ« interesante pĂ«r tĂ« pĂ«rmirĂ«suar performancĂ«n. Dhe mjaft tĂ« fuqishme â nĂ« kuptimin, kam punuar me kĂ«to gjĂ«ra nĂ« pĂ«rpunimin e tĂ« dhĂ«nave pĂ«r fintech, dhe kjo ka ofruar njĂ« pĂ«rparim rreth pesĂ« herĂ«. Ky Ă«shtĂ« njĂ« pĂ«rparim i madh, sidomos nĂ« botĂ«n ku procesorĂ«t nuk po bĂ«hen mĂ« tĂ« shpejtĂ«, dhe ne ende vazhdojmĂ« tĂ« presim pĂ«rmirĂ«sime.
Career of a performance engineer
Andrey: Gjithashtu, do tĂ« doja tĂ« pyesja pĂ«r karrierĂ«n nĂ« pĂ«rgjithĂ«si. Keni qĂ«nĂ« tĂ« njohur pĂ«r punĂ«n tuaj nĂ« JIT nĂ« HotSpot, e mĂ« pas u sistemuat nĂ« Azul â dhe kjo Ă«shtĂ« gjithashtu njĂ« kompani JVM. Por tani mĂ« shumĂ« jeni marrĂ« me harduerin se sa me softuerin. MĂ« pas, papritur u kaluat nĂ« Big Data dhe Machine Learning, e mĂ« pas nĂ« zbulimin e mashtrimeve. Si ndodhi kjo? KĂ«to janĂ« fusha shumĂ« tĂ« ndryshme tĂ« zhvillimit.
Cliff: Kam unë kam bërë programim për një kohë të gjatë dhe kam pasur mundësi të merrem me aktivitete shumë të ndryshme. Dhe kur njerëzit thonë: «O, ti je ai që bëri JIT për Java!», gjithmonë është argëtuese. Por përpara se të lidhesha me këtë, kam punuar mbi një klon të PostScript, gjuhës që Apple e përdorte dikur për printerët e saj lazer. Para kësaj, kam realizuar gjuhën Forth. Mendoj se tema kryesore për mua është zhvillimi i mjeteve. Gjatë gjithë jetës time, kam krijuar mjete me të cilat njerëzit e tjerë shkruajnë programet e tyre të shkëlqyera. Por kam qenë i angazhuar edhe në zhvillimin e sistemeve operative, drejtuesve, debugger-it të nivelit të bërthamës, gjuhëve për zhvillimin e OS-ve, të cilat filluan thjesht, por me kalimin e kohës u bëheshin gjithnjë e më të ndërlikuara. Por tema kryesore, ndonëse, mbetet zhvillimi i mjeteve. Një pjesë e madhe e jetës time ka kaluar midis Azul dhe Sun, dhe ajo kishte të bëjë me Java. Por kur fillova të merrem me Big Data dhe Machine Learning, e veshja përsëri kapelen time të veçantë dhe thashë: «Ah, tani kemi një problem të rëndësishëm, dhe këtu po ndodhin shumë gjëra interesante dhe njerëz që bëjnë diçka». Ky është një rrugë e shkëlqyer për t'u zhvilluar, e cila ia vlen të ecet.
Po, gjatĂ« jetĂ«s time kam pasur njĂ« pasion tĂ« madh pĂ«r llogaritĂ« e shpĂ«rndara. Puna ime e parĂ« ishte gjatĂ« studentĂ«ve, duke punuar me C pĂ«r njĂ« projekt reklamash. Kjo ishin llogari tĂ« shpĂ«rndara nĂ« çipat Zilog Z80, tĂ« cilĂ«t mbledhin tĂ« dhĂ«na pĂ«r njohjen optike tĂ« tekstit, duke u kryer nga njĂ« analizues analogjik. Ishte njĂ« temĂ« e mrekullueshme dhe krejt e çuditshme. MegjithatĂ«, kishte probleme, ndonjĂ« pjesĂ« nuk interpretohej siç duhej, prandaj ishte e nevojshme qĂ« tĂ« merrnim imazhin dhe t'ia tregonim njĂ« njeriu qĂ« e kishte lexuar me sytĂ« e tij dhe qĂ« informonte se çfarĂ« thoshte teksti, dhe kĂ«shtu kishte punĂ« me tĂ« dhĂ«na, dhe kĂ«to punĂ« kishin gjuhĂ«n e tyre. Kishte njĂ« backend qĂ« e pĂ«rpunonte gjithçka â Z80 qĂ« punonin paralelisht me terminalet vt100 â njĂ« pĂ«r çdo person, dhe kishte njĂ« model programimi paralel nĂ« Z80. NjĂ« pjesĂ« e pĂ«rbashkĂ«t memorie qĂ« ndante tĂ« gjitha Z80 brenda njĂ« konfigurimi tĂ« tipit âyllâ; ndarja e backplane dhe gjysma e RAM-it ndante brenda rrjetit, dhe gjysma tjetĂ«r ishte private ose shkonte diku tjetĂ«r. NjĂ« sistem paralel dhe tĂ« shpĂ«rndarĂ« mjaft kompleks me memorie të⊠gjysmĂ« tĂ« ndarĂ«. Kur u ndodhi⊠Nuk e mbaj mend saktĂ«sisht, diku nĂ« mes tĂ« viteve 80. Mjaft kohĂ« mĂ« parĂ«.Â
Po, le tĂ« themi se 30 vjet janĂ« mjaft kohĂ« mĂ« parĂ«. Problemet qĂ« lidhen me llogaritĂ« e shpĂ«rndara ekzistojnĂ« prej njĂ« kohe tĂ« konsiderueshme, njerĂ«zit pĂ«r njĂ« kohĂ« tĂ« gjatĂ« kanĂ« luftuar me to. -klasteret. KĂ«to klastere duken si... P.sh.: ka Ethernet dhe procesori yt i shpejtĂ« x86 Ă«shtĂ« lidhur me kĂ«tĂ« Ethernet, dhe tani dĂ«shiron tĂ« marrĂ«sh memorien e pĂ«rbashkĂ«t fake, sepse askush nuk mund tĂ« merrej me kodimin e llogaritjeve tĂ« shpĂ«rndara, ishte shumĂ« e komplikuar dhe pĂ«r kĂ«tĂ« arsye kishte memorien e pĂ«rbashkĂ«t fake me mbrojtjen e faqeve tĂ« memories nĂ« x86, dhe nĂ«se shkruaje nĂ« kĂ«tĂ« faqe, ne u thoshim procesorĂ«ve tĂ« tjerĂ« qĂ« nĂ«se ata do tĂ« kishin qasje nĂ« tĂ« njĂ«jtĂ«n memorie tĂ« pĂ«rbashkĂ«t, do tĂ« duhej ta ngarkonin nga ti, dhe kĂ«shtu lindi diçka si njĂ« protokoll mbĂ«shtetje pĂ«r koherencĂ«n e caches dhe software pĂ«r kĂ«tĂ«. NjĂ« koncept interesant. Problemi i vĂ«rtetĂ«, natyrisht, ishte ndryshe. E gjithĂ« kjo funksiononte, por ti shpejt kishe probleme me performancĂ«n, sepse askush nuk e kuptonte modelin e performancĂ«s nĂ« njĂ« nivel tĂ« mjaftueshĂ«m tĂ« mirĂ« â cilat ishin ato modele tĂ« qasjes nĂ« memorie, si tĂ« bĂ«je qĂ« nodet tĂ« mos pingonin pafund njĂ«ra-tjetrĂ«n, etj.
Në H2O kam menduar kështu: zhvilluesit vetë janë përgjegjës për të përcaktuar se ku është paralelizmi dhe ku nuk ka. Kam krijuar një model kodimi që e bën të lehtë dhe të thjeshtë shkruajnë kod me performancë të lartë. Ndërsa të shkruash kod që punon ngadalë është e vështirë; ai do të duket keq. Duhet të përpiqesh seriozisht për të shkruar kod të ngadalshëm, do të duhet të përdorësh metoda të natyrshme. Kodi që pengon është i dukshëm që në shikim të parë. Si pasojë, zakonisht shkruhet kod që punon shpejt, por ju duhen të kuptoni se çfarë të bëni në rast të memories së ndarë. Të gjitha këto janë të lidhura me masa të mëdha dhe sjellja aty është e ngjashme me masat e mëdha jo volatile në Java paralel. Për shembull, imagjinoni se dy rrjedha shkruajnë në një masë paralel, njëra fiton dhe tjetra, përkatësisht, humbet, dhe nuk dini se cila është cila. Nëse ato nuk janë volatile, rendi mund të jetë çfarëdo - dhe kjo funksionon me të vërtetë mirë. Njerëzit vërtetë shqetësohen për rendin e operacioneve, ata rendisin siç duhet volatile dhe në vendet e duhura presin probleme me performancën që lidhen me memorien. Në të kundërt, ata do të shkruanin thjesht kod si cikle nga 1 në N, ku N është disa triliona, duke shpresuar se të gjitha rastet komplekse do të bëhen automatikisht të paralelizuara - dhe atje kjo nuk funksionon. Por në H2O nuk është as Java dhe as Scala, mund ta quani këtë "Java minus minus" nëse dëshironi. Ky është një stil programimi shumë i kuptueshëm dhe është i ngjashëm me shkruarjen e kodit të thjeshtë në C ose Java me cikle dhe masa. Por, edhe kësaj mund të trajtojmë terabajtë memorjeje. Unë ende përdor H2O. Herë pas here e përdor në projekte të ndryshme - dhe ajo ende është gjëja më e shpejtë, me dhjetëra herë përpara konkurrentëve. Nëse po bëni Big Data me të dhëna kolonore, është shumë e vështirë të kaloni H2O.
Technical challenges
Andrey: Cila ka qenë sfida më e madhe gjatë gjithë karrierës suaj?
Cliff: Po diskutojmĂ« pjesĂ«n teknike apo jo teknike tĂ« çështjes? Do tĂ« thoja, sfidat mĂ« tĂ« mĂ«dha janĂ« ato jo teknike.Â
Sa ndihmuar në sfidat teknike. Unë thjesht i kam mposhtur ato. Nuk e di se cila ka qenë më e madhja, por kishte disa mjaft interesante që morën shumë kohë dhe luftë mendore. Kur shkova në Sun, isha i sigurt se do të bëja një kompilator të shpejtë, ndërsa një grup seniorësh në përgjigje thoshin se nuk do të mundja kurrë. Por unë vazhdova në këtë rrugë, shkrova një kompilator deri në alokimin e regjistrave dhe ishte mjaft i shpejtë. Ai ishte aq i shpejtë sa kompajleri modern C1, por atëherë alokatori ishte shumë më i ngadaltë, dhe duke e parë pas, kjo ishte një problem që kishte një strukturë të madhe të dhënash. Më nevojitej për të shkruar një alokator grafik regjistrash dhe nuk e kuptoja dilemën ndërmjet shprehshmërisë së kodit dhe shpejtësisë, e cila ekzistonte atëherë dhe ishte shumë e rëndësishme. Doli që struktura e të dhënave zakonisht e tejkalonte madhësinë e cache-it në x86-të e asaj kohe dhe prandaj, nëse fillimisht supozova se alokatori i regjistrave do të punonte 5-10 për qind të gjithë kohës së jitimit, në realitet kjo rezultoi në 50 për qind.
Koha kalonte, kompajleri po bĂ«hej gjithnjĂ« e mĂ« i qartĂ« dhe produktiv, ndaloi sĂ« gjeneruari kod tĂ« tmerrshĂ«m mĂ« shpesh, dhe performanca filloi tĂ« ngjajĂ« mĂ« shumĂ« me atĂ« qĂ« jep kompajleri C. NĂ«se, sigurisht, nuk po shkruaje ndonjĂ« gjĂ« tĂ« keqe, qĂ« madje as C nuk e pĂ«rshpejton. NĂ«se shkruan kod si nĂ« C, merr performancĂ« si nĂ« C nĂ« shumĂ« mĂ« shumĂ« raste. Dhe sa mĂ« shumĂ« kalonte koha, aq mĂ« shpesh del kodi, asimptotikisht pĂ«rputhĂ«s me nivelin C, alokatori i regjistrave filloi tĂ« ngjajĂ« me diçka tĂ« pĂ«rfunduar⊠pavarĂ«sisht nĂ«se kodi yt punon shpejt apo ngadalĂ«. UnĂ« vazhdoja tĂ« punoja mbi alokatorin pĂ«r ta bĂ«rĂ« atĂ« qĂ« tĂ« bĂ«nte alokime mĂ« tĂ« mira. Ai po bĂ«hej gjithnjĂ« e mĂ« i ngadaltĂ«, por po siguronte performancĂ« gjithnjĂ« e mĂ« tĂ« mirĂ« nĂ« ato raste kur askush tjetĂ«r nuk arrinte. Munda tĂ« zhytem nĂ« alokatorin e regjistrave, tĂ« thelloj njĂ« muaj punĂ« atje, dhe papritmas i gjithĂ« kodi fillonte tĂ« ekzekutohej 5% mĂ« shpejt. Kjo ndodhte herĂ« pas here dhe alokatori i regjistrave u bĂ« diçka si njĂ« vepĂ«r arti â tĂ« gjithĂ« e donin apo e urrejnin atĂ«, dhe njerĂ«zit nga akademia bĂ«nin pyetje si "pĂ«rse gjithçka bĂ«het pikĂ«risht kĂ«shtu", pse jo , dhe si ndryshon ajo. PĂ«rtĂ«ritja Ă«shtĂ« e njĂ«jtĂ«: njĂ« alokator i bazuar nĂ« ngjyrosjen e grafit plus njĂ« menaxhim shumĂ« tĂ« kujdesshĂ«m tĂ« kodit tampon i barabartĂ« me njĂ« armĂ« fitoreje, kombinimi mĂ« i mirĂ« qĂ« askush nuk mund ta mposht. Dhe kjo Ă«shtĂ« njĂ« gjĂ« mjaft e papritur. TĂ« gjitha gjĂ«rat e tjera qĂ« bĂ«n kompiler Ă«shtĂ« mjaft tĂ« njohura, megjithatĂ« janĂ« çuar nĂ« njĂ« nivel arti. UnĂ« gjithmonĂ« kam bĂ«rĂ« gjĂ«ra qĂ« duhet tĂ« kthenin kompilerin nĂ« njĂ« vepĂ«r arti. Por asgjĂ« nga kĂ«to nuk ishte diçka jashtĂ«zakonisht tĂ« jashtme â pĂ«rveç alokatorit tĂ« regjistrave. Truku Ă«shtĂ« se duhet tĂ« jesh shumĂ« i kujdesshĂ«m nĂ« ngarkesĂ« dhe, nĂ«se ndodh kjo (mund tĂ« shpjegoj mĂ« hollĂ«sisht, nĂ«se Ă«shtĂ« e interesuar), kjo do tĂ« thotĂ« se mund tĂ« in-line mĂ« agresivisht, pa rrezik tĂ« kalosh pĂ«rtej thyerjes sĂ« grafikut tĂ« performancĂ«s. NĂ« ato kohĂ« ka pasur shumĂ« kompilerĂ« tĂ« plotĂ«, tĂ« mbushur me zbukurime dhe rrotulla, nĂ« tĂ« cilat kishte alokatorĂ« regjistrash, por askush tjetĂ«r nuk mundi ta bĂ«jĂ« mĂ«.
Problemi Ă«shtĂ« se, nĂ«se shton metodat qĂ« nĂ«nshkruhen pĂ«r inlining, duke rritur vazhdimisht fushĂ«n e inlining, grupi i vlerave tĂ« pĂ«rdorura menjĂ«herĂ« tejkalon numrin e regjistrave, dhe duhet tĂ« spillohet. Niveli kritik zakonisht ndodh kur alokatori dorĂ«zohet, dhe njĂ« kandidat i mirĂ« pĂ«r spilling vlen aq sa njĂ« tjetĂ«r, dhe spillon disa gjĂ«ra krejtĂ«sisht tĂ« çmendura. Vlera e inlining Ă«shtĂ« se humbasin njĂ« pjesĂ« tĂ« overhead-it, overhead-it tĂ« thirrjes dhe ruajtjes, mund tĂ« shohĂ«sh vlerat brenda dhe mund t'i optimizosh mĂ« tej. Kostumi i inlining Ă«shtĂ« se krijohet njĂ« numĂ«r i madh i vlerave aktive, dhe nĂ«se alokatori yt i regjistrave spillon mĂ« shumĂ« se sa duhet, humb menjĂ«herĂ«. Prandaj, shumica e alokatorĂ«ve kanĂ« njĂ« problem: kur inlining kalon njĂ« pikĂ« tĂ« caktuar, fillon tĂ« spillohet gjithçka dhe performanca mund tĂ« bjerĂ« nĂ« ujĂ« tĂ« ndotur. Ata qĂ« realizojnĂ« njĂ« kompilator shtojnĂ« disa heuristika: pĂ«r shembull, pĂ«r tĂ« ndaluar inlining, duke filluar nga njĂ« madhĂ«si mjaft e madhe, pasi alokimet e shkatĂ«rrojnĂ« gjithçka. KĂ«shtu krijohet njĂ« thyerje nĂ« grafikun e performancĂ«s â ke inlinuar, inlinuar, performanca rritet ngadalĂ« â dhe pastaj hop! â bie poshtĂ« me njĂ« kthesĂ« tĂ« shpejtĂ«, sepse ke inlinuar shumĂ«. KĂ«shtu ka ndodhur deri nĂ« ardhjen e Java. Java kĂ«rkon shumĂ« mĂ« tepĂ«r inlining, prandaj mĂ« Ă«shtĂ« dashur tĂ« bĂ«j alokatorin tim mĂ« agresiv, nĂ« mĂ«nyrĂ« qĂ« tĂ« rregullohej dhe tĂ« mos binte, dhe nĂ«se ke inlinuar shumĂ« â ai fillon tĂ« spillohet, por mĂ« vonĂ« gjithsesi vjen njĂ« moment kur 'nuk ka mĂ« spilling'. Kjo Ă«shtĂ« njĂ« vĂ«zhgim interesant dhe mĂ« erdhi thjesht nga asgjĂ«, e paqartĂ«, por e mirĂ«paguar. MĂ« ndoqi inlining agresiv dhe kjo mĂ« çoi nĂ« vende ku performanca e Java dhe C shkon krahas. Ato janĂ« me tĂ« vĂ«rtetĂ« tĂ« afĂ«rta â mund tĂ« shkruaj kod nĂ« Java qĂ« do tĂ« jetĂ« shumĂ« mĂ« i shpejtĂ« se kodi nĂ« C dhe kĂ«shtu me radhĂ«, por nĂ« tĂ« mesme, nĂ« pamjen e madhe tĂ« gjĂ«rave, ato janĂ« afĂ«rsisht tĂ« krahasueshme. Mendoj se pjesa e kĂ«tij meriti Ă«shtĂ« alokatori i regjistrave, i cili mĂ« lejon tĂ« inlinoj nĂ« mĂ«nyrĂ« maksimalisht tĂ« thjeshtĂ«. UnĂ« thjesht inlinoj gjithçka qĂ« shoh. Pyetja kĂ«tu Ă«shtĂ« nĂ«se alokatori punon mirĂ«, nĂ«se rezultati Ă«shtĂ« njĂ« kod funkcional. Ky ka qenĂ« njĂ« sfidĂ« e madhe: tĂ« kuptoj gjithçka kĂ«tĂ« dhe ta bĂ«j atĂ« tĂ« funksionojĂ«.
A bit about register allocation and multithreading
Vladimir: Problemet si alokimi i regjistrave duket një temë e pafund. A është ndodhur ndonjëherë që një ide të duket premtuese, por më pas të dështojë në praktikë?
Cliff: Sigurisht! Alokimi i regjistrave Ă«shtĂ« njĂ« fushĂ« ku pĂ«r tĂ« zgjidhur njĂ« problem NP-tĂ« plotĂ«, pĂ«rpiqesh tĂ« gjesh disa heuristika. Dhe asnjĂ«herĂ« nuk mund tĂ« arrish njĂ« zgjidhje perfekte, apo jo? ĂshtĂ« thjesht e pamundur. Shihni, kompaktimi i Paraprakisht â ai gjithashtu punon keq. Biseda kĂ«tu Ă«shtĂ« pĂ«r raste tĂ« zakonshme. PĂ«r performancĂ«n tipike, kĂ«shtu qĂ« mund tĂ« shkosh dhe tĂ« matĂ«sh diçka qĂ« mendon se Ă«shtĂ« njĂ« performancĂ« tipike e mirĂ« â pĂ«rfundimisht, ti po punon pĂ«r ta pĂ«rmirĂ«suar atĂ«! Alokimi i regjistrave Ă«shtĂ« njĂ« temĂ« krejtĂ«sisht e dedikuar performancĂ«s. Sapo tĂ« kesh prototipin e parĂ«, ai funksionon dhe ngjyros atĂ« qĂ« duhet, fillon puna pĂ«r performancĂ«n. Duhet tĂ« mĂ«sosh tĂ« matesh mirĂ«. Pse Ă«shtĂ« kaq e rĂ«ndĂ«sishme? NĂ«se ka tĂ« dhĂ«na tĂ« qarta, mund tĂ« shohĂ«sh pjesĂ« tĂ« ndryshme dhe tĂ« shohĂ«sh: aha, kjo ndihmoi kĂ«tu, por aty gjĂ«rat shkuan keq! Shfaqen disa ide tĂ« mira, shton njĂ« heuristik tĂ« re dhe papritmas gjithçka fillon tĂ« funksionojĂ« pak mĂ« mirĂ« mesatarisht. Ose ndoshta jo. Kam pasur shumĂ« raste kur kemi luftuar pĂ«r pesĂ« pĂ«rqind tĂ« performancĂ«s qĂ« e ndanĂ« zhvillimin tonĂ« nga alokatori i mĂ«parshĂ«m. Dhe çdo herĂ« duket kĂ«shtu: diku fitove, diku humbe. NĂ«se ke mjete tĂ« mira pĂ«r analizĂ«n e performancĂ«s, mund tĂ« gjesh idetĂ« qĂ« humbin dhe tĂ« kuptosh pse ato humbin. Ndoshta ia vlen tĂ« lĂ«sh gjithçka siç Ă«shtĂ«, ose ndoshta tĂ« merresh seriozisht me pĂ«rshtatjen fine, ose tĂ« shkosh dhe tĂ« rregullosh diçka tjetĂ«r. Kjo Ă«shtĂ« njĂ« shumĂ«llojshmĂ«ri e madhe! Kam bĂ«rĂ« kĂ«tĂ« haks tĂ« mrekullueshĂ«m, por mĂ« nevojitet edhe ky, ky, dhe ky â dhe gjithashtu kombinimi i tyre jep disa pĂ«rmirĂ«sime. NdĂ«rsa tĂ« vetmet mund tĂ« dĂ«shtojnĂ«. Kjo Ă«shtĂ« natyra e punĂ«s nĂ« problemet NP-tĂ« plotĂ« tĂ« performancĂ«s.
Vladimir: Duke parĂ« situatĂ«n, duket se gjĂ«rat si ngjyrimi nĂ« alokatorĂ«t janĂ« njĂ« problem tashmĂ« i zgjidhur. Pra, pĂ«r ju tĂ« zgjidhur, gjykuar nga ajo qĂ« thoni, atĂ«herĂ« a ka ndonjĂ« kuptimâŠ
Cliff: Ajo nuk Ă«shtĂ« zgjidhur si e tillĂ«. Ti duhet ta kthesh atĂ« nĂ« «tĂ« zgjidhur». Ka detyra tĂ« vĂ«shtira dhe ato duhen zgjidhur. Kur kjo Ă«shtĂ« bĂ«rĂ«, vjen koha pĂ«r tĂ« punuar mbi performancĂ«n. Kjo punĂ« duhet tĂ« merret seriozisht â tĂ« kryhen benchmark, tĂ« mblidhen metrika, tĂ« shpjegohen situatat kur rikthimi nĂ« versionin e mĂ«parshĂ«m bĂ«n qĂ« haku yt i vjetĂ«r tĂ« fillojĂ« tĂ« funksionojĂ« pĂ«rsĂ«ri (apo anasjelltas, tĂ« ndalojĂ«). Dhe mos u dorĂ«zo derisa tĂ« arrish diçka. Siç kam thĂ«nĂ«, nĂ«se ide tĂ« shkĂ«lqyera qĂ« nuk funksionuan, por nĂ« fushĂ«n e alokimit tĂ« regjistrave ka ide pothuajse tĂ« pafund. Mund, pĂ«r shembull, tĂ« lexosh publikime shkencore. MegjithatĂ«, tani kjo fushĂ« ka filluar tĂ« lĂ«vizĂ« mĂ« ngadalĂ« dhe Ă«shtĂ« bĂ«rĂ« mĂ« e qartĂ« se nĂ« ditĂ«t e saj tĂ« reja. MegjithatĂ«, nĂ« kĂ«tĂ« fushĂ« punon njĂ« pafundĂ«si njerĂ«zish dhe tĂ« gjitha idetĂ« e tyre meritojnĂ« tĂ« provohen, tĂ« gjithĂ« po presin momentin e tyre. Dhe ti nuk mund tĂ« thua sa tĂ« mira janĂ« ato, nĂ«se nuk provon. Sa mirĂ« integrohen me gjithçka tjetĂ«r nĂ« alokuesin tĂ«nd, sepse alokuesi bĂ«n shumĂ« gjĂ«ra, dhe disa ide nĂ« alokuesin tĂ«nd specifik nuk do tĂ« funksionojnĂ«, ndĂ«rsa nĂ« njĂ« alokues tjetĂ«r â lehtĂ«sisht. MĂ«nyra primare e fitores pĂ«r alokuesin Ă«shtĂ« tĂ« nxjerrĂ« gjĂ«rat e ngadalta jashtĂ« rrugĂ«s kryesore dhe tĂ« detyruar tĂ« bĂ«jĂ« ndarje pĂ«rgjatĂ« kufijve tĂ« rrugĂ«ve tĂ« ngadalta. Prandaj, nĂ«se dĂ«shiron tĂ« nisĂ«sh GC, tĂ« shkosh nĂ« rrugĂ«n e ngadalshme, tĂ« deoptimizohesh, tĂ« hedhĂ«sh njĂ« pĂ«rjashtim, gjithçka nĂ« atĂ« frymĂ« â di se kĂ«to gjĂ«ra janĂ« relativisht tĂ« rralla. Dhe ato janĂ« vĂ«rtet tĂ« rralla, e kam provuar. BĂ«n punĂ« shtesĂ« dhe pĂ«r kĂ«tĂ« arsye eliminon shumĂ« kufizime nĂ« kĂ«to rrugĂ« tĂ« ngadalta, por kjo nuk Ă«shtĂ« shumĂ« e rĂ«ndĂ«sishme, sepse ato janĂ« tĂ« ngadalta dhe rrallĂ« shihen. PĂ«r shembull, treguesi zero â ai kurrĂ« nuk ndodh, apo jo? Duhet tĂ« kesh disa rrugĂ« pĂ«r gjĂ«ra tĂ« ndryshme, por ato nuk duhet tĂ« pĂ«rzihen nĂ« tĂ« parĂ«n.Â
Vladimir: ĂfarĂ« mendoni pĂ«r shumĂ«nukĂ«sinĂ«, kur ka mijĂ«ra bĂ«rthama? A Ă«shtĂ« njĂ« gjĂ« e dobishme?
Cliff: Suksesi i GPU tregon se është mjaft i dobishëm!
Vladimir: Ata janë mjaft të specializuar. E çfarë për procesorët e përgjithshëm?
Cliff: E, kjo ishte modeli i biznesit tĂ« Azul. PĂ«rgjigjja erdhi nĂ« njĂ« epokĂ« kur njerĂ«zit e donin shumĂ« performancĂ«n e parashikueshme. AtĂ«herĂ« ishte e vĂ«shtirĂ« tĂ« shkruaje kod paralel. Modeli i kodimit H2O shkallĂ«zohet mirĂ«, por nuk Ă«shtĂ« njĂ« model me qĂ«llim tĂ« pĂ«rgjithshĂ«m. Ndryshe nga ai qĂ« pĂ«rdor GPU-nĂ«. Po flasim pĂ«r kompleksitetin e zhvillimit tĂ« njĂ« gjĂ«je tĂ« tillĂ« apo pĂ«r kompleksitetin e pĂ«rdorimit tĂ« saj? PĂ«r shembull, njĂ« mĂ«sim interesant mĂ« jep Azul, mjaft i padukshĂ«m: caches tĂ« vogla janĂ« tĂ« pranueshme.Â
The biggest challenge in life
Vladimir: ĂfarĂ« pĂ«r sfidat jo teknike?
Cliff: Sfida mĂ« e madhe ishte tĂ« mos isha... i mirĂ« dhe i dashur me njerĂ«zit. Dhe si pasojĂ«, unĂ« u gjenda vazhdimisht nĂ« situata ekstremisht konfliktuale. Situata ku dija se çdo gjĂ« po shkonte keq, por nuk dija si tĂ« ecja pĂ«rpara nĂ« zgjidhjen e kĂ«tyre problemeve dhe nuk mund tĂ« merresha me to. Mjaft probleme tĂ« vazhdueshme, qĂ« zgjatĂ«n gjatĂ« dhjetĂ«ra vjetĂ«ve, u shfaqĂ«n saktĂ«sisht nĂ« kĂ«tĂ« mĂ«nyrĂ«. E vĂ«rteta qĂ« nĂ« Java ka kompilatorĂ« C1 dhe C2 Ă«shtĂ« njĂ« pasojĂ« e drejtpĂ«rdrejtĂ« e kĂ«saj. Fakti qĂ« nĂ« Java pĂ«r njĂ« dekadĂ« nuk kishte kompilim shumĂ«-niveli Ă«shtĂ« gjithashtu njĂ« pasojĂ« e drejtpĂ«rdrejtĂ«. Sigurisht, na duhej njĂ« sistem i tillĂ«, por nuk Ă«shtĂ« e qartĂ« pse nuk kishte. Kam pasur probleme me njĂ« inxhinier... ose grup inxhinierĂ«sh. Disa kohĂ« mĂ« parĂ«, kur fillova punĂ«n nĂ« Sun, isha... MirĂ«, jo vetĂ«m atĂ«herĂ«, kam gjithmonĂ« njĂ« mendim pĂ«r gjithçka. Dhe e mendoja se Ă«shtĂ« njĂ« e vĂ«rtetĂ« qĂ« mund tĂ« marrĂ«sh kĂ«tĂ« tĂ« vĂ«rtetĂ« time dhe ta tregosh hapur. PĂ«r mĂ« tepĂ«r, isha shokueshĂ«m i saktĂ« pjesĂ«n mĂ« tĂ« madhe tĂ« kohĂ«s. Dhe nĂ«se njĂ« qasje e tillĂ« nuk tĂ« pĂ«lqen... sidomos nĂ«se Ă«shtĂ« e qartĂ« qĂ« je nĂ« gabim dhe po bĂ«n gjĂ«ra tĂ« padobishme... NĂ« pĂ«rgjithĂ«si, shumĂ« pak njerĂ«z mund tĂ« pĂ«rballonin njĂ« formĂ« komunikimi tĂ« tillĂ« me tolerancĂ«. MegjithatĂ« disa mundeshin, pĂ«r shembull, unĂ«. E kam ndĂ«rtuar tĂ«rĂ« jetĂ«n time mbi parimet meritokratike. NĂ«se mĂ« tregon diçka tĂ« gabuar, unĂ« menjĂ«herĂ« do tĂ« kthehem dhe do tĂ« them: ke thĂ«nĂ« njĂ« budallallĂ«k. NĂ« tĂ« njĂ«jtĂ«n kohĂ«, sigurisht, kĂ«rkoj falje dhe gjĂ«ra tĂ« tjera tĂ« tilla, do tĂ« theksoj meritat, nĂ«se ka ndonjĂ« qĂ« ekziston, dhe do tĂ« bĂ«j veprime tĂ« tjera tĂ« duhura. Nga ana tjetĂ«r, unĂ« jam shokueshĂ«m i saktĂ« njĂ« pĂ«rqindje shokueshĂ«m tĂ« madhe tĂ« kohĂ«s sĂ« pĂ«rgjithshme. Dhe kjo nuk funksionon shumĂ« mirĂ« nĂ« marrĂ«dhĂ«nie me njerĂ«zit. UnĂ« nuk pĂ«rpiqem tĂ« jem i kĂ«ndshĂ«m, por e bĂ«j çështjen tĂ« qartĂ«. âKjo nuk do tĂ« funksionojĂ« kurrĂ«, sepse njĂ«, dy dhe treâ. Dhe ata janĂ« si: âOh!â. Kishin edhe pasoja tĂ« tjera, tĂ« cilat ndoshta do ishte mĂ« mirĂ« tâi kalonim: pĂ«r shembull, ato qĂ« çuan nĂ« divorcin nga bashkĂ«shortja dhe dhjetĂ« vjet depresion pas kĂ«saj.
Sfida është një betejë me njerëzit, me perceptimin e tyre për atë që ti mund ose nuk mund të bësh, çfarë është e rëndësishme dhe çfarë nuk është. Ka pasur shumë sfida për stilin e kodimit. Unë akoma shkruaj shumë kod, dhe në ato kohëra më duhej madje të ngadalësohesha, sepse bëja shumë detyra paralelisht dhe i bëja ato keq, në vend që të fokusoja në njërën e vetme. Kur e shoh pas, kam shkruar gjysmën e kodit të ekipit Java JIT, ekipit C2. Programuesi tjetër më i shpejtë shkruante me gjysmë më ngadalë, ai pas tij - akoma më ngadalë dhe kjo ishte një rënie eksponenciale. Personi i shtatë në këtë rresht ishte shumë, shumë ngadalë - kështu ka ndodhur gjithmonë! Unë e kam prekur një sërë kodi. Kam parë se kush shkruan çfarë, pa përjashtim, e kam parë kodin e tyre, kam bërë rishikime për secilin prej tyre, dhe akoma kam vazhduar të shkruaj më shumë se çdo njeri tjetër. Me njerëzit ky qasje nuk funksionon shumë mirë. Disa nuk e pëlqejnë atë. Dhe kur ata nuk janë në gjendje të përballen me këtë, fillojnë të gjitha llojet e ankesave. Për shembull, një herë më thanë të ndalojë së shkruari kod, sepse shkruaj tepër shumë kod, dhe kjo rrezikon ekipin, dhe për mua e gjithë kjo tingëllonte si një shaka: çuna, nëse e gjithë pjesa tjetër e ekipit zhduket, dhe unë vazhdoj të shkruaj kod, do të humbni vetëm gjysmën e ekipit. Nga ana tjetër, nëse unë vazhdoj të shkruaj kod dhe ju humbni gjysmën e ekipit - kjo tingëllon si menaxhim shumë i keq. Unë kurrë nuk kam menduar shumë për këtë, kurrë nuk kam folur për këtë, por gjithsesi ka qenë diku në mendjen time. Në thellësi të mendjeve tona, kishte një mendim: 'A po humoroni?'. Pra, problemi më i madh isha unë dhe marrëdhëniet e mia me njerëzit. Tani e kuptoj veten shumë më mirë, kam qenë udhëheqës ekipi për programuesit për një kohë të gjatë, dhe tani u them njerëzve të tjerë: e di, jam kështu siç jam, dhe do të duhet të përballeni me mua - a është në rregull nëse qëndroj këtu? Dhe kur ata filluan të përballen me këtë, gjithçka funksionoi. Sepse, në fakt, nuk jam as i keq, as i mirë, nuk kam ndonjë qëllim të keq ose ambicie egoiste, kjo është thjesht natyra ime dhe duhet të jetojmë me këtë.
Andrey: SĂ« fundmi, tĂ« gjithĂ« filluan tĂ« flasin pĂ«r vetĂ«dijen pĂ«r introvertĂ«t, dhe nĂ« pĂ«rgjithĂ«si pĂ«r aftĂ«sitĂ« e buta. ĂfarĂ« mund tĂ« thuhet pĂ«r kĂ«tĂ«?
Cliff: Po, ishte njĂ« kuptim dhe njĂ« mĂ«sim qĂ« nxora nga divorcimi me gruan. Ajo qĂ« nxora nga divorci Ă«shtĂ« kuptimi i vetes. KĂ«shtu fillova tĂ« kuptoj edhe tĂ« tjerĂ«t. PĂ«r tĂ« kuptuar se si funksionon kjo ndĂ«rveprimin. Kjo solli zbulime pas zbulimeve. Filloi tĂ« kuptohet kush jam dhe çfarĂ« pĂ«rfaqĂ«soj. ĂfarĂ« po bĂ«j: a jam i shqetĂ«suar pĂ«r detyrĂ«n, a po shmang konfliktin, apo diçka tjetĂ«r â dhe njĂ« nivel i tillĂ« vetĂ«dijesimi nĂ« tĂ« vĂ«rtetĂ« ndihmon tĂ« mbash veten nĂ«n kontroll. Pas kĂ«saj, gjithçka shkon mĂ« lehtĂ«. NjĂ« gjĂ« qĂ« kam zbuluar jo vetĂ«m te vetja, por edhe te programuesit e tjerĂ« â pamundĂ«sia pĂ«r tĂ« verbalizuar mendimet kur je nĂ« njĂ« gjendje stresi emocional. PĂ«r shembull, po kodifikon dhe je nĂ« njĂ« gjendje fluksi, dhe papritmas vijnĂ« dhe fillojnĂ« tĂ« ulĂ«rasin nĂ« panik se diçka Ă«shtĂ« prishur, dhe tani do tĂ« tĂ« shqyrtojnĂ« masa ekstreme. Dhe nuk mund tĂ« thuash asnjĂ« fjalĂ«, sepse je nĂ« njĂ« gjendje stresi emocional. NjohuritĂ« e fituara tĂ« lejojnĂ« tĂ« pĂ«rgatitesh pĂ«r atĂ« moment, ta kalosh dhe tĂ« kalosh nĂ« njĂ« plan tĂ« tĂ«rheqjes, pas sĂ« cilĂ«s mund tĂ« bĂ«sh diçka. Pra, po, kur fillon tĂ« kuptosh se si funksionon e gjithĂ« kjo â Ă«shtĂ« njĂ« ngjarje e madhe, qĂ« ndryshon jetĂ«n.Â
UnĂ« vetĂ« nuk arrita tĂ« gjej fjalĂ«t e duhura, por mbajta mend radhitjen e veprimeve. Thelbi Ă«shtĂ« se kjo reagim Ă«shtĂ« aq fizik sa Ă«shtĂ« verbalisht, dhe tĂ« duhet hapĂ«sirĂ«. NjĂ« hapĂ«sirĂ« e tillĂ«, nĂ« kuptimin zen. PikĂ«risht kĂ«tĂ« duhet tĂ« shpjegosh, dhe pastaj menjĂ«herĂ« tĂ« tĂ«rhiqesh nĂ« anĂ« â fizikisht tĂ« tĂ«rhiqesh. Kur hesht fizikisht, mund tĂ« pĂ«rballosh situatĂ«n nĂ« pjesĂ«n e emocioneve. NdĂ«rsa adrenalina arrin nĂ« tru, tĂ« kalon nĂ« modin
Dhe kjo kĂ«rkon njĂ« hapĂ«sirĂ« verbale. Thjesht njĂ« hapĂ«sirĂ« tĂ« lirĂ«. NĂ«se do flasĂ«sh pĂ«r ndonjĂ« gjĂ«, mund tĂ« thua kĂ«tĂ« dhe pastaj tĂ« shkosh dhe realisht tĂ« gjesh "hapĂ«sirĂ«n": tĂ« shkosh pĂ«r njĂ« shĂ«titje nĂ« park, tĂ« mbyllesh nĂ« dush â nuk ka rĂ«ndĂ«si. E rĂ«ndĂ«sishme Ă«shtĂ« tĂ« shkĂ«putesh pĂ«rkohĂ«sisht nga ajo situatĂ«. Sa herĂ« qĂ« tĂ« shkĂ«putesh pĂ«r disa sekonda, kontrolli kthehet, fillon tĂ« mendosh qartĂ«. "MirĂ«, nuk jam ndonjĂ« idiot, nuk po bĂ«j gjĂ«ra mendjelehta, jam njĂ« njeri mjaft i dobishĂ«m". Sa herĂ« qĂ« ke arritur ta bindĂ«sh veten, Ă«shtĂ« koha tĂ« kalosh nĂ« hapin tjetĂ«r: tĂ« kuptosh se çfarĂ« ndodhi. Ti u sulmua, sulmi erdhi nga njĂ« vend ku nuk e kishe pritur, ishte njĂ« kurth i pabesĂ« e tĂ« ulĂ«t. Kjo Ă«shtĂ« e keqe. Hapi tjetĂ«r â tĂ« kuptosh se pĂ«rse sulmuesi e kishte tĂ« domosdoshme kĂ«tĂ«. Me tĂ« vĂ«rtetĂ«, pĂ«rse? Ndoshta sepse ai vetĂ« ishte nĂ« zemĂ«rim? Pse ai Ă«shtĂ« nĂ« zemĂ«rim? PĂ«r shembull, ndoshta sepse ai dĂ«shtoi dhe nuk mund tĂ« pranojĂ« pĂ«rgjegjĂ«sinĂ«? Ky Ă«shtĂ« mĂ«nyra e duhur pĂ«r tĂ« trajtuar situatĂ«n me kujdes. Por pĂ«r kĂ«tĂ«, nevojitet njĂ« hapĂ«sirĂ« manovrimi, njĂ« hapĂ«sirĂ« verbale. Hapi i parĂ« mĂ« i rĂ«ndĂ«sishĂ«m â tĂ« prishĂ«sh kontaktin verbal. TĂ« largohemi nga diskutimi me fjalĂ«. Ta anashkalosh atĂ«, tĂ« ikĂ«sh sa mĂ« shpejt. NĂ«se Ă«shtĂ« njĂ« bisedĂ« telefonike â thjesht vendos telefonin â ky Ă«shtĂ« njĂ« aftĂ«si qĂ« e kam fituar nga komunikimi me ish-gruan. NĂ«se biseda nuk sjell asgjĂ« tĂ« mirĂ«, thjesht thuaj "mirupafshim" dhe vendos telefonin. Nga ana tjetĂ«r e linjĂ«s: "bla-bla-bla", ti pĂ«rgjigjesh: "po, mirupafshim!" dhe e vendos telefonin. Thjesht ndĂ«rpres bisedĂ«n. PĂ«sĂ« minuta mĂ« vonĂ«, kur tĂ« kthehet aftĂ«sia pĂ«r tĂ« menduar qartĂ«, ti je pak mĂ« i qetĂ«, Ă«shtĂ« e mundur tĂ« mendosh pĂ«r atĂ« qĂ« ndodhi dhe çfarĂ« do ndodhĂ« mĂ« pas. Dhe tĂ« fillosh tĂ« formosh njĂ« pĂ«rgjigje tĂ« menduar, dhe jo thjesht tĂ« reagosh emocionalisht. PĂ« pĂ«r mua, njĂ« pĂ«rparim nĂ« vetĂ«dijesimin ka qenĂ« pikĂ«risht se nĂ« rast stresi emocional, unĂ« nuk mund tĂ« flas. TĂ« dalĂ«sh nga ky gjendje, tĂ« mendosh dhe tĂ« planifikosh mĂ«nyrĂ«n si tĂ« pĂ«rgjigjesh dhe si tĂ« kompensosh problemet â kĂ«to janĂ« hapat e duhur kur nuk mund tĂ« flasĂ«sh. MĂ«nyra mĂ« e thjeshtĂ« â tĂ« ikĂ«sh nga situata nĂ« tĂ« cilĂ«n shfaqet stresi emocional dhe thjesht tĂ« ndalosh tĂ« marrĂ«sh pjesĂ« nĂ« atĂ« stres. Pas kĂ«saj, ti fiton aftĂ«sinĂ« tĂ« mendosh, kur mund tĂ« mendosh, ke mundĂ«sinĂ« tĂ« flasĂ«sh, dhe kĂ«shtu me radhĂ«.
A thua, nĂ« gjyq avokati i palĂ«s tjetĂ«r pĂ«rpiqet tĂ« tĂ« bĂ«jĂ« kĂ«tĂ« â tani Ă«shtĂ« e qartĂ« pse. Sepse ai ka mundĂ«sinĂ« tĂ« tĂ« shtypĂ« deri nĂ« njĂ« gjendje ku nuk mund as tĂ« thuash emrin tĂ«nd, pĂ«r shembull. NĂ« kuptimin mĂ« tĂ« drejtpĂ«rdrejtĂ«, nuk do tĂ« mundesh tĂ« flasĂ«sh. NĂ«se kjo po tĂ« ndodh dhe nĂ«se e di se do tĂ« jesh nĂ« njĂ« vend ku fjalĂ«t bĂ«hen luftĂ«, nĂ« njĂ« vend si gjykata, atĂ«herĂ« mund tĂ« shkosh me avokatin tĂ«nd. Avokati do tĂ« tĂ« mbrojĂ« dhe do tĂ« ndalojĂ« sulmin verbal, dhe do ta bĂ«jĂ« kĂ«tĂ« nĂ« njĂ« mĂ«nyrĂ« krejtĂ«sisht ligjore, dhe do tĂ« rikthesh hapĂ«sirĂ«n tĂ«nde zen tĂ« humbur. PĂ«r shembull, mua mĂ« Ă«shtĂ« dashur disa herĂ« tĂ« telefonoj familjen, gjyqtari Ă«shtĂ« marrĂ« me kĂ«tĂ« mjaft miqĂ«sisht, por avokati i palĂ«s tjetĂ«r vazhdonte tĂ« mĂ« kritikonin me zĂ« tĂ« lartĂ«, nuk mundesha as tĂ« ndĂ«rhyja. NĂ« raste tĂ« tilla, mĂ«nyra mĂ« e mirĂ« pĂ«r mua Ă«shtĂ« pĂ«rdorimi i njĂ« ndĂ«rmjetĂ«si. NdĂ«rmjetĂ«si ndalon gjithĂ« kĂ«tĂ« presion, qĂ« tĂ« del me njĂ« fluks tĂ« vazhdueshĂ«m, ti zbulon hapĂ«sirĂ«n e nevojshme zen, dhe me tĂ« rikthehet aftĂ«sia pĂ«r tĂ« folur. Kjo Ă«shtĂ« njĂ« fushĂ« e tĂ«rĂ« njohurish, nĂ« tĂ« cilĂ«n duhet tĂ« mĂ«sosh shumĂ«, tĂ« zbulohet shumĂ« nĂ« brendĂ«si, dhe gjithçka kjo shndĂ«rrohet nĂ« vendime strategjike tĂ« niveleve tĂ« larta, tĂ« ndryshme pĂ«r njerĂ«z tĂ« ndryshĂ«m. Disa njerĂ«z nuk e kanĂ« kĂ«tĂ« problem tĂ« pĂ«rshkruar mĂ« lart, zakonisht, ata nuk e kanĂ« ata qĂ« profesionistĂ«t e shitjeve. TĂ« gjithĂ« ata njerĂ«z qĂ« fitojnĂ« jetesĂ«n me fjalĂ« â kĂ«ngĂ«tarĂ« tĂ« njohur, poetĂ«, figura tĂ« besimit dhe politikanĂ«, ata gjithmonĂ« kanĂ« diçka pĂ«r tĂ« thĂ«nĂ«. Ata nuk kanĂ« kĂ«to probleme, ndĂ«rsa unĂ« i kam.
Andrey: Ishte⊠befasuese. Po, ne kemi biseduar mjaft dhe është koha ta mbyllim këtë intervistë. Ne patjetër do të takohemi në konferencë dhe do të mund të vazhdojmë këtë dialog. Takohuni në Hydra!
Mund të vazhdohet biseda me Kliffin në konferencën Hydra 2019, e cila do të mbahet më 11-12 korrik 2019 në Shën Petersburg. Ai do të vijë me një prezantim . Biletat mund të blihen .
Burimi: habr.com
