{"id":35851,"date":"2019-10-31T22:07:03","date_gmt":"2019-10-31T19:07:03","guid":{"rendered":"https:\/\/prohoster.info\/blog\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java\/"},"modified":"2019-10-31T22:07:03","modified_gmt":"2019-10-31T19:07:03","slug":"bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","title":{"rendered":"Veliki intervju sa Kliffom Klikom \u2014 ocem JIT kompilacije u Javi","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Veliki intervju sa Kliffom Klikom \u2014 ocem JIT kompilacije u Javi\" src=\"\/wp-content\/uploads\/2019\/07\/9ea9740ef74c0ae14d334482af115222.png\" style=\"display:block;margin: 0 auto;\" \/><strong>Cliff Click<\/strong> \u2014 CTO of Cratus (IoT sensors for process improvement), founder and co-founder of several startups (including Rocket Realtime School, Neurensic, and H2O.ai) with multiple successful exits. Cliff wrote his first compiler at 15 (Pascal for TRS Z-80)! He is best known for his work on C2 in Java (the Sea of Nodes IR). This compiler showed the world that JIT can produce quality code, which became one of the factors for Java's emergence as one of the main modern software platforms. Later, Cliff helped Azul Systems build an 864-core mainframe with software in pure Java that supported GC pauses on a 500-gigabyte heap within 10 milliseconds. Overall, Cliff has worked on all aspects of the JVM.<br clear=\"all\"><br \/>\n\u00a0<br \/>\nThis post on Habrahabr is a large interview with Cliff. We will discuss the following topics:<\/p>\n<p><\/p>\n<ul>\n<li>Transitioning to low-level optimizations<\/li>\n<li>How to conduct large refactoring<\/li>\n<li>Cost model<\/li>\n<li>Learning low-level optimizations<\/li>\n<li>Practical examples of performance improvements<\/li>\n<li>Why create your own programming language<\/li>\n<li>Career of a performance engineer<\/li>\n<li>Technical challenges<\/li>\n<li>A bit about register allocation and multithreading<\/li>\n<li>The biggest challenge in life<\/li>\n<\/ul>\n<p><\/p>\n<p>The interviewers are:<\/p>\n<p><\/p>\n<ul>\n<li><strong>Andrey Satarin<\/strong> from Amazon Web Services. He has worked in a variety of projects throughout his career: testing a distributed NewSQL database at Yandex, a cloud detection system at Kaspersky Lab, a multiplayer game at Mail.ru, and a currency pricing service at Deutsche Bank. Interested in testing large-scale backend and distributed systems.<\/li>\n<li><strong>Vladimir Sitnikov<\/strong> from Netcracker. He has worked for ten years on the performance and scalability of NetCracker OS \u2014 software used by telecom operators for automating network management processes and network equipment. He is passionate about Java and Oracle Database performance. Author of over a dozen performance improvements in the official PostgreSQL JDBC driver.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"perehod-k-nizkourovnevym-optimizaciyam\">Transitioning to low-level optimizations<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: You are a well-known figure in the world of JIT compilation, Java, and performance work in general, right?\u00a0<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Absolutely!<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Let's start with general questions about working on performance. What do you think about choosing between high-level and low-level optimizations like working at the CPU level?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Tukaj je vse preprosto. Najhitrej\u0161a koda je tista, ki nikoli ne za\u017eene. Zato je treba vedno za\u010deti z visokim nivojem, delati na algoritmih. Bolj\u0161a O-notacija premaga slab\u0161o O-notacijo, razen \u010de se ne vme\u0161ajo velike konstance. Nizkonivojski elementi pridejo na vrsto \u0161ele na koncu. Obi\u010dajno, \u010de ste optimizirali preostanek sklada dovolj dobro in ostane \u0161e kaj zanimivega \u2013 to je nizka raven. Kako pa za\u010deti z visokim nivojem? Kako vedeti, da ste opravili dovolj dela na visoki ravni? No\u2026 nikakor. Ni pripravljenih receptov. Treba je razumeti problem, re\u0161iti, kaj nameravate narediti (da ne naredite nepotrebnih korakov), in \u0161ele nato lahko vzamete profiler, ki vam lahko pove kaj koristnega. V nekem trenutku sami ugotovite, da ste se znebili nepotrebnih stvari in pri\u0161el je \u010das za fino nastavitev nizke ravni. To je brez dvoma posebna vrsta umetnosti. Veliko ljudi dela nepotrebne stvari, a se gibljejo tako hitro, da nimajo \u010dasa skrbeti za zmogljivost. Vendar to velja, dokler se ne pojavi nujna te\u017eava. Obi\u010dajno 99% \u010dasa nikogar ne zanima, s \u010dim se ukvarjam, do trenutka, ko na kriti\u010dni poti ne pride do pomembne stvari, za katero je nekomu mar. In takrat vsi za\u010dnejo spra\u0161evati: \u00bbZakaj ni bilo od za\u010detka popolno?\u00ab Na splo\u0161no vedno obstaja kaj, kar je treba izbolj\u0161ati v zmogljivosti. Vendar pa 99% \u010dasa nimate nikakr\u0161nih namigov! Preprosto posku\u0161ate nekaj spraviti v delo in ob tem razumete, kaj je pomembno. Nikoli ne morete vnaprej vedeti, kateri kos je treba narediti popoln, zato morate v bistvu biti popolni v vsem. Kar je nemogo\u010de, in tako ne delate. Vedno je veliko stvari, ki jih je treba popraviti \u2013 in to je povsem normalno.<\/p>\n<p><\/p>\n<h1 id=\"kak-delat-bolshoy-refaktoring\">How to conduct large refactoring<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Kako delate na zmogljivosti? To je vendar pre\u010dkalna te\u017eava. Na primer, ali ste se kdaj ukvarjali s problemi, ki izhajajo iz prekrivanja velike koli\u010dine \u017ee obstoje\u010de funkcionalnosti?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Trudim se da to izbegnem. Ako znam da \u0107e performanse postati problem, razmi\u0161ljam o tome pre nego \u0161to po\u010dnem da pi\u0161em kod, posebno o strukturama podataka. No, \u010desto sve to otkrijete kasnije. I tada morate pre\u0107i na ekstremne mere i uraditi ono \u0161to nazivam \u201eprepisuj i vladaj\u201d: treba uhvatiti dovoljno veliki deo. Deo koda tako\u0111e morate prepisati zbog problema sa performansama ili iz nekog drugog razloga. Koji god razlog za prepisivanje koda bio, skoro uvek je bolje prepisati ve\u0107i deo nego manji. U tom trenutku, svi po\u010dinju da se boje: \u201eoh, Bo\u017ee, ne mo\u017eemo dirati toliko koda!\u201d. Ali, zapravo, takav pristup obi\u010dno funkcioni\u0161e mnogo bolje. Treba odmah uhvatiti veliki problem, obele\u017eiti ga velikim krugom i re\u0107i: sve unutar kruga, ja \u0107u prepisati. Granica je mnogo manja od sadr\u017eaja unutar nje koji treba zameniti. I ako takvo ocrtavanje granica omogu\u0107i savr\u0161eno obavljanje posla unutar \u2013 ruke su ti slobodne, radi \u0161ta \u017eeli\u0161. Kada shvati\u0161 problem, proces prepisivanja ide mnogo lak\u0161e, zato uzmi veliki zalogaj!<br \/>\nU isto vreme, kada prepisuje\u0161 veliki deo i shvati\u0161 da \u0107e performanse postati problem, mo\u017ee\u0161 odmah po\u010deti da brine\u0161 o tome. Obi\u010dno se to pretvara u jednostavne stvari poput \u201ene kopiraj podatke, upravljaj podacima \u0161to je jednostavnije mogu\u0107e, smanjite ih\u201d. U velikim prepisivanjima, postoje standardni na\u010dini za pobolj\u0161anje performansi. I oni se skoro uvek vrte oko podataka.<\/p>\n<p><\/p>\n<h1 id=\"model-stoimosti\">Cost model<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: U jednom od podkasta ste govorili o modelima tro\u0161kova u kontekstu performansi. Mo\u017eete li objasniti na \u0161ta ste mislili?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Seveda. Rojen sem bil v \u010dasu, ko je bila zmogljivost procesorja izjemno pomembna. In ta doba se ponovno vra\u010da - usoda ni brez ironije. Za\u010del sem \u017eiveti v \u010dasu osmibitnih ra\u010dunalnikov, moj prvi ra\u010dunalnik je delal z 256 bajti. To\u010dno tako, bajti. Vse je bilo zelo majhno. Moral si \u0161teti ukaze in takoj ko smo za\u010deli napredovati po lestvici programskih jezikov, so jeziki prevzeli vse ve\u010d obveznosti. Bil je Assembler, nato Basic, nato C, in C je prevzel naloge z mnogimi podrobnostmi, kot sta dodelitev registrov in optimizacija ukazov. Vse to je bilo precej jasno in \u010de sem naredil kazalec na instanco spremenljivke, sem dobil load, in za ta ukaz je bila cena znana. Strojna oprema da dolo\u010den broj strojnih ciklov, tako da lahko hitro izra\u010duna\u0161 \u010das izvajanja razli\u010dnih stvari samo s se\u0161tevanjem vseh ukazov, ki jih namerava\u0161 zagnati. Vsak compare\/test\/branch\/call\/load\/store se je lahko se\u0161tel in si si rekel: tu je tvoj \u010das izvajanja. Ko se ukvarja\u0161 z izbolj\u0161anjem zmogljivosti, zagotovo opazi\u0161, kak\u0161ne \u0161tevilke pripadajo majhnim vro\u010dim ciklom.\u00a0<br \/>\nToda takoj ko preklopi\u0161 na Java, Python in podobne zadeve, se hitro oddalji\u0161 od nizkolo\u010dljivih strojnih komponent. Kak\u0161na je cena klica getterja v Javi? \u010ce je JIT v HotSpot vse pravilno <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.openjdk.java.net\/display\/HotSpot\/Inlining\">in-linjal<\/a><\/noindex>, bo to load, \u010de pa tega ni storil - bo to klic funkcije. Ker je klic v vro\u010dem ciklu, bo odpravil vse druge optimizacije v tem ciklu. Zato bo dejanska cena veliko vi\u0161ja. In takoj izgubi\u0161 sposobnost, da pogleda\u0161 na del kode in razume\u0161, koliko nas bo stalo izvajanje v smislu frekvence procesorja, uporabljene pomnilnika in predpomnilnika. Vse to postane zanimivo \u0161ele, ko se resno poglobi\u0161 v zmogljivost.<br \/>\nTrenutno smo se na\u0161li u situaciji gdje brzine procesora ve\u0107 vi\u0161e od deset godina gotovo da ne rastu. Stara vremena se vra\u0107aju! Vi vi\u0161e ne mo\u017eete ra\u010dunati na dobru jednonitnu izvedbu. No, ako se slu\u010dajno odlu\u010dite za paralelno ra\u010dunalstvo \u2013 to je nevjerojatno slo\u017eeno, svi vas gledaju kao da ste James Bond. Deset puta bolji ishodi obi\u010dno se javljaju na mjestima gdje je netko ne\u0161to propustio. Paralelnost zahtijeva puno posla. Da biste dobili to desetostruko pobolj\u0161anje, morate razumjeti model tro\u0161kova. \u0160to i koliko ko\u0161ta. A za to morate razumjeti kako se jezik uklapa u temeljni hardver.<br \/>\nMartin Thompson je prona\u0161ao odli\u010dnu rije\u010d za svoj blog <noindex><a rel=\"nofollow\" href=\"https:\/\/mechanical-sympathy.blogspot.com\/\">Mehani\u010dka simpatija<\/a><\/noindex>! Potrebno je razumjeti \u0161to \u0107e hardver raditi, kako \u0107e to raditi i za\u0161to uop\u0107e radi to \u0161to radi. Koriste\u0107i to, prili\u010dno je jednostavno po\u010deti brojati instrukcije i utvrditi kamo vrijeme izvr\u0161enja odlazi. Ako nemate odgovaraju\u0107u izobrazbu, samo tra\u017eite crnu ma\u010dku u tamnoj sobi. Konstantno vidim ljude koji optimiziraju performanse, a nemaju ni najmanju ideju \u0161to zapravo rade. Veoma se mu\u010de i ne napreduju nigdje. A kada preuzmem isti komad koda, ubacim nekoliko sitnih trikova i dobijem petostruko ili desetostruko pobolj\u0161anje, oni ka\u017eu: pa, to nije po\u0161teno, znali smo da si bolji. Nevjerojatno. O \u010demu sam to... model tro\u0161kova \u2013 to je o tome \u0161to kod pi\u0161ete i kako brzo on u prosjeku radi u cijeloj slici.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: I kako takav volumen zadr\u017eati u glavi? To se posti\u017ee velikim iskustvom, zar ne? Gdje se to iskustvo stje\u010de?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Pa, svoje iskustvo stekao sam na prili\u010dno te\u017eak na\u010din. Programirao sam u Assembleru jo\u0161 u vrijeme kada se moglo razumjeti svaka pojedina\u010dna instrukcija. Ovo zvu\u010di glupo, ali od tada mi je u glavi, u sje\u0107anju, zauvijek ostao skup instrukcija Z80. Ne sje\u0107am se imena ljudi ve\u0107 minutu nakon razgovora, ali pamtim kod napisan prije 40 godina. Zabavno, izgleda kao sindrom \u201e<noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%B8%D0%BD%D0%B4%D1%80%D0%BE%D0%BC_%D1%81%D0%B0%D0%B2%D0%B0%D0%BD%D1%82%D0%B0\">znanstvenog idiota<\/a><\/noindex>\u00bb.<\/p>\n<p><\/p>\n<h1 id=\"obuchenie-nizkourovnevym-optimizaciyam\">Learning low-level optimizations<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Postoji li neki jednostavniji na\u010din da se u\u0111e u poslovanje?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Da i ne. Oprema koju svi koristimo tokom ovog vremena nije se mnogo promenila. Svi koriste x86, osim pametnih telefona koji se oslanjaju na Arm. Ako se ne bavi\u0161 ne\u010dim ozbiljnim u embedded svetu, koristi\u0161 sve isto. Dobro, idemo dalje. Uputstva se tako\u0111e vekovima nisu menjala. Treba da ode\u0161 i napi\u0161e\u0161 ne\u0161to na Assembleru. Malo, ali dovoljno da po\u010dne\u0161 da razume\u0161. Vi se sme\u0161kate, ali ja to govorim sasvim ozbiljno. Potrebno je razumeti odnos izme\u0111u jezika i hardvera. Posle toga, trebalo bi da krene\u0161, napi\u0161e\u0161 malo i napravi\u0161 mali igra\u010dka kompajler za mali igra\u010dka jezik. \u201eIgra\u010dka\u201c zna\u010di da ga treba napraviti u razumnom vremenskom okviru. Mo\u017ee biti super jednostavan, ali mora generisati instrukcije. Akt generisanja instrukcija pomo\u0107i \u0107e razumevanju modela tro\u0161kova za most izme\u0111u visoko-nivnog koda, na kojem svi pi\u0161u, i ma\u0161inskog koda koji se izvr\u0161ava na hardveru. Ova korelacija urezat \u0107e se u umu dok pi\u0161e\u0161 kompajler. \u010cak i najjednostavniji kompajler. Nakon toga mo\u017ee\u0161 po\u010deti da posmatra\u0161 Javu i uo\u010di\u0161 da njen semanti\u010dki razmak je mnogo dublji, i ulogu izgradnje mostova preko toga je mnogo te\u017ee. U Javi je mnogo te\u017ee shvatiti da li je na\u0161 most dobar ili lo\u0161, \u0161to \u0107e ga dovesti do propadanja ili ne. Ali ti je potrebna odre\u0111ena polazna ta\u010dka kada gleda\u0161 kod i razume\u0161: \u201eaha, ovaj getter bi trebao da se inline-uje svaki put\u201c. A onda se ispostavi da se to ponekad de\u0161ava, osim kada metoda postane prevelika i JIT po\u010dne da inline-uje sve. Performanse takvih mesta mogu se predvideti trenutno. Obi\u010dno getteri dobro funkcioni\u0161u, ali onda gleda\u0161 velike vru\u0107e petlje i shvata\u0161 da tu plivaju neki pozivi funkcija \u010dija svrha nije jasna. U tome i jeste problem sa sveprisutnom upotrebom gettera, razlog zbog kojeg se ne inline-ju \u2013 nije jasno da li je to getter. Ako ima\u0161 super malu bazu koda, mo\u017ee\u0161 je jednostavno zapamtiti i kasnije re\u0107i: ovo je getter, a ovo je setter. U velikoj bazi koda svaka funkcija ima svoju pri\u010du koja, u su\u0161tini, nikome nije poznata. Profajler govori da smo izgubili 24% vremena na nekoj petlji i da bi shvatio \u0161ta ta petlja radi, mora\u0161 pogledati svaku funkciju unutar nje. Nemogu\u0107e je to razumeti bez prou\u010davanja funkcije, \u0161to ozbiljno usporava proces razumevanja. Zato ja ne koristim gettere i settere, pre\u0161ao sam na novi nivo!<br \/>\nKje pridobiti model cen? No, lahko preberem kaj, seveda ... Ampak mislim, da je najbolj\u0161i na\u010din ukrepanje. Narediti majhen prevajalnik in to bo najbolj\u0161i na\u010din, da se zavedamo modela cen in ga umestimo v svoje misli. Majhen prevajalnik, ki bi bil uporaben za programiranje mikrovalovke - to je naloga za za\u010detnika. Mislim, da ti bodo tvoje programske ve\u0161\u010dine \u017ee dovolj. Vse te stvari, kot je raz\u010dlenitev niza, ki bo kak\u0161no algebrai\u010dno izraze, pridobivanje navodil matemati\u010dnih operacij v pravilnem zaporedju, pridobitev pravih vrednosti iz registrov - vse to se lahko naredi zlahka. In medtem ko to po\u010dne\u0161, se to vtisne v spomin. Mislim, da vsi vedo, s \u010dem se ukvarja prevajalnik. In to bo dalo razumevanje modela cen.<\/p>\n<p><\/p>\n<h1 id=\"prakticheskie-primery-uluchsheniya-proizvoditelnosti\">Practical examples of performance improvements<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Na kaj \u0161e moramo biti pozorni pri delu na zmogljivosti?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Strukture podatkov. Mimogrede, \u017ee dolgo nisem imel teh predavanj ... <noindex>Rocket School<\/noindex>. Bila je zabavna, a je zahtevala toliko truda, pa imam vendarle tudi svoje \u017eivljenje! No. Torej, na enem od velikih in zanimivih predavanj, \"Kam gre va\u0161a zmogljivost\", sem \u0161tudentom dal primer: dva in pol gigabajta finan\u010dnih podatkov, ki so jih prebrali iz CSV datoteke in nato je bilo treba izra\u010dunati \u0161tevilo prodanih izdelkov. Obi\u010dajni podatki o trgovanju. UDP paketi, spremenjeni v besedilni format, od 70-ih let naprej. Chicago Mercantile Exchange - razli\u010dne stvari, kot so olje, koruza, sojini stroki in podobno. Treba je bilo pre\u0161teti te izdelke, \u0161tevilo trgov, povpre\u010dno vrednost gibanja sredstev in blaga itd. To je razmeroma preprosta trgovinska matematika: najti kodo izdelka (to je 1-2 znaka v ha\u0161 tabeli), pridobiti vsoto, jo dodati v en nabor trgov, dodati obseg, dodati vrednost in \u0161e nekaj drugih stvari. Zelo preprosta matematika. Igra\u010dka implementacija je bila zelo enostavna: vse je bilo v datoteki, prebral sem datoteko in se gibal po njej, razdelil posamezne zapise na Java nize, iskal potrebne stvari in se\u0161teval po zgoraj opisani matematiki. In to deluje z neko majhno hitrostjo. <\/p>\n<p><\/p>\n<p>S tovrim pristupom je sve jasno, \u0161to se doga\u0111a, i paralelno ra\u010dunanje ovde ne mo\u017ee pomo\u0107i, zar ne? Ispostavlja se da se petostruko pove\u0107anje performansi mo\u017ee posti\u0107i samo izborom pravih struktura podataka. To \u010dak iznena\u0111uje i iskusne programere! U mom konkret\u043d\u043e\u043c slu\u010daju, fokus je bio na tome da ne treba raditi alokacije memorije u vru\u0107em ciklusu. Pa, to nije cela istina, ali u su\u0161tini \u2013 ne treba alocirati 'jednom u X', kada je X dovoljno veliko. Kada je X dva i po gigabajta, ne treba alocirati ni\u0161ta 'jednom po znaku', ili 'jednom po redu', ili 'jednom po polju', ni\u0161ta u tom smislu. Ta\u010dno na to odlazi vreme. Kako to zapravo funkcioni\u0161e? Zamislite, ja pozivam <code>String.split()<\/code> ili <code>BufferedReader.readLine()<\/code>. <code>Readline<\/code> pravi string iz skupa bajtova koji je stigao kroz mre\u017eu, jednom za svaku liniju, za svaku od stotina miliona linija. Uzimam ovaj string, analiziram ga i odbacujem. Za\u0161to odbacujem \u2013 pa, ve\u0107 sam ga obradio, to je to. Dakle, za svaku bajt koji je pro\u010ditan iz tih 2.7G, bi\u0107e upisani dva karaktera u stringu, to jest ve\u0107 5.4G, i oni mi vi\u0161e nisu potrebni, tako da se odbacuju. Ako pogledamo propusnost memorije, u\u010ditavamo 2.7G, koji prolaze kroz memoriju i memorijsku magistralu u procesoru, i zatim duplo vi\u0161e odlazi u string koji le\u017ei u memoriji, i sve to se mije\u0161a prilikom kreiranja svake nove linije. Ali ja moram to pro\u010ditati, hardver to \u010dita, \u010dak i ako \u0107e sve kasnije biti prebrisan. I moram to zapisati, jer sam kreirao string i ke\u0161evi su se napunili \u2013 ke\u0161 ne mo\u017ee smestiti 2.7G. Stoga, za svaki o\u010ditani bajt, ja \u010ditam jo\u0161 dva dodatna bajta i upisujem dva dodatna bajta, i na kraju imamo odnos 4:1 \u2013 u tom odnosu bespotrebno tro\u0161imo propusnost memorije. A ispostavlja se da ako radim <code>String.split()<\/code> \u2013 radim to daleko ne poslednji put, unutra mo\u017ee biti jo\u0161 6-7 polja. Zato klasi\u010dni kod za \u010ditanje CSV-a sa naknadnim parsiranjem linija dovodi do gubitaka propusne trake memorije od oko 14:1 u odnosu na ono \u0161to biste zapravo \u017eeleli da imate. Ako se odbace te alokacije, mo\u017ee se posti\u0107i petostruko ubrzanje. <\/p>\n<p><\/p>\n<p>In fact, it's not very complicated. If you look at the code from the right angle, it becomes quite straightforward as soon as you grasp the essence of the problem. You should never stop allocating memory: the issue is merely that you allocate something and it immediately dies, consuming vital resources in the process, which in this case is memory bandwidth. All of this results in a drop in performance. On x86, you generally need to actively burn CPU cycles, whereas here you\u2019ve wasted all your memory much earlier. The solution is to reduce the number of allocations.\u00a0<br \/>\nAnother part of the problem is that if you run a profiler when the memory bandwidth is exhausted, right at that moment, you usually expect the cache to return because it's filled with garbage created by all those strings you just produced. Therefore, every load or store operation becomes slow, as they lead to cache misses\u2014 the entire cache becomes sluggish, waiting for the garbage to be cleared out. Consequently, the profiler will mainly show warm random noise spread across the entire cycle\u2014 there will be no distinct hot instruction or section in the code. Just noise. And if you look at the GC cycles, they will all be on the Young Generation and super fast\u2014microseconds or milliseconds at most. This is because all that memory dies instantly. You're allocating billions of gigabytes, and it slices and slices and slices again. It all happens very quickly. So, there are cheap GC cycles, warm noise throughout the cycle, but we want to achieve a 5x acceleration. At this moment, something should click in your mind and resonate: \"Why is this happening?!\" Memory bandwidth overflow isn\u2019t represented in a classic debugger; you need to run a performance hardware counter debugger and see it directly for yourself. However, indirectly you can suspect it from these three symptoms. The third symptom is when you look at what you allocate, ask the profiler, and it replies: \"You created a billion strings, but the GC executed for free.\" Once this happens, you realize you've produced too many objects and burned through all the memory bandwidth. There is a way to figure this out, but it\u2019s not obvious.\u00a0<\/p>\n<p><\/p>\n<p>Te\u017eava je v strukturi podatkov: gola struktura, ki stoji za vsem, kar se dogaja, je prevelika, zaseda 2.7G na disku, zato je zelo neza\u017eeleno narediti kopijo te stvari \u2013 \u017eeleli bi jo takoj nalo\u017eiti iz omre\u017enega bajtnega predpomnilnika v registre, da je ne bi brali in zapisovali petkrat nazaj in naprej. Na \u017ealost Java privzeto ne nudi tak\u0161ne knji\u017enice v okviru JDK. Ampak to je przecie\u017c trivialno, ane? V bistvu gre za 5-10 vrstic kode, ki bodo izvedle lastnega predpomnjenega nalagalnika vrstic, ki ponavlja vedenje razreda vrstic, hkrati pa predstavlja ovitek okoli osnovnega bajtnega predpomnilnika. Posledi\u010dno deluje\u0161 skoraj kot bi delal z vrsti, vendar v resnici premikajo pokazatelji na predpomnilnik, surovi bajti pa se nikamor ne kopirajo, tako da se znova in znova uporabljajo isti predpomnilniki, operacijski sistem pa je vesel, da prevzame naloge, za katere je namenjen, kot je skrito dvojno predpomnjenje teh bajtnih predpomnilnikov, ti pa ve\u010d ne predeluje\u0161 neskon\u010dnega toka nepotrebnih podatkov. Mimogrede, razumete, da pri delu z GC zagotavlja, da vsako dodeljevanje pomnilnika ne bo vidno procesorju po zadnjem ciklu GC? Zato vse to ne more biti v predpomnilniku, in potem pride do 100%-garantiranega zadetka. Pri delu s kazalcem na x86 branje registra iz pomnilnika traja 1-2 cikla, in takoj, ko se to zgodi, pla\u010da\u0161, pla\u010da\u0161, pla\u010da\u0161, ker je celotna pomnilnik na <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cache_inclusion_policy\">NINE predpomnilnikih<\/a><\/noindex> \u2013 in to je stro\u0161ek dodeljevanja pomnilnika. Pravi stro\u0161ek.<\/p>\n<p><\/p>\n<p>Drugimi besedami, podatkovne strukture so tisto, kar je najte\u017eje spremeniti. In ko enkrat spoznate, da ste izbrali napa\u010dno podatkovno strukturo, ki bo kasneje uni\u010dila u\u010dinkovitost, obi\u010dajno zahteva veliko dela, da to spremenite, vendar, \u010de tega ne storite, bo \u0161e slab\u0161e. Najprej morate razmi\u0161ljati o podatkovnih strukturah, to je pomembno. Glavni stro\u0161ek tukaj pade na kompleksne podatkovne strukture, ki jih za\u010dnemo uporabljati v slogu \u201ekopiral sem podatkovno strukturo X v podatkovno strukturo Y, ker mi je Y bolj v\u0161e\u010d v obliki\u201c. Ampak operacija kopiranja (ki se zdi poceni) dejansko porabi pomnilni\u0161ki pas in tukaj se skriva celotna izguba \u010dasa izvajanja. \u010ce imam ogromno vrstico z JSON in jo \u017eelim spremeniti v strukturirano DOM drevo iz POJO ali kaj takega, bo operacija raz\u010dlenitve te vrstice in ustvarjanje POJO ter nato novo klicanje POJO pomenilo dodatne stro\u0161ke \u2013 to ni poceni. Razen, \u010de boste klicali POJO bistveno pogosteje kot vrstico. Pribli\u017eno, lahko namesto tega poskusite razvozlati vrstico in izvle\u010di le tisto, kar potrebujete, ne da bi to pretvorili v kakr\u0161ne koli POJO. \u010ce se vse to dogaja na poti, kjer je potrebna najvi\u0161ja u\u010dinkovitost, nobenih POJO, \u2013 morate nekako neposredno kopati v vrstici.<\/p>\n<p><\/p>\n<h1 id=\"zachem-sozdavat-svoy-yazyk-programmirovaniya\">Why create your own programming language<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Rekli ste, da je za razumevanje modela stro\u0161kov potrebno napisati svoj majhen jezik...<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ne jezik, ampak prevajalnik. Jezik in prevajalnik sta razli\u010dni stvari. Najpomembnej\u0161a razlika je v va\u0161i glavi.\u00a0<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Mimogrede, kolikor vem, eksperimentirate pri ustvarjanju svojih jezikov. Zakaj?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ker ker jih lahko! Sem pol upokojen, zato je to moje hobiranje. Vse \u017eivljenje sem uresni\u010deval jezike nekoga drugega. Tudi veliko sem delal na slogu kodiranja. In tudi zato, ker vidim te\u017eave v drugih jezikih. Vidim, da so bolj\u0161i na\u010dini za opravljanje obi\u010dajnih nalog. In jih z veseljem uporabim. Preprosto me utrujajo te\u017eave, ki jih imam v sebi, v Javi, v Pythona, v katerem koli drugem jeziku. Zdaj pi\u0161em v React Native, JavaScript in Elm kot hobi, ki ni povezano z upokojitvijo, ampak z aktivnim delom. Tudi v Pythonu pi\u0161em in verjetno bom \u0161e naprej delal na strojni inteligenci za Java backende. Obstaja veliko priljubljenih jezikov, vsaka ima svoje zanimive zna\u010dilnosti. Vsak je dober po svoje, in mogo\u010de poskusiti zdru\u017eiti te funkcije. Tako da se ukvarjam z u\u010denjem stvari, ki so mi zanimive, obna\u0161anjem jezika, posku\u0161am razviti smiselno semantiko. In zaenkrat mi gre dobro! Trenutno se borim s semantiko spomina, ker \u017eelim imeti tak\u0161en spomin kot v C in Javi, in izvesti mo\u010dan model spomina in semantiko za nalaganja in shranjevanja. Hkrati pa \u017eelim imeti avtomatsko izpeljavo tipov kot v Haskell. Tukaj posku\u0161am zdru\u017eiti Haskell-podobno izpeljavo tipov s spominom, ki deluje kot v C in Javi. S tem se ukvarjam zadnje 2-3 mesece, na primer.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: \u010ce gradite jezik, ki jemlje najbolj\u0161e vidike iz drugih jezikov, ste pomislili, da bi nekdo lahko naredil obratno: vzel va\u0161e ideje in jih uporabil pri sebi?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Prav tako nastajajo novi jeziki! Zakaj je Java podobna C? Ker je C imel dober sintakti\u010dni na\u010din, ki so ga vsi razumeli, in Java se je navdihnila pri tej sintaksi, dodala tipno varnost, preverjanje meja nizov, GC, poleg tega pa so izbolj\u0161ali nekatere stvari iz C. Dodali so svoje. A mo\u010dno so se navdihovali, mar ne? Vsi stojimo na ramah velikanov, ki so bili pred nami \u2013 tako se ustvarja napredek.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Kolikor razumem, bo va\u0161 jezik varen glede uporabe spomina. Ste pomislili, da bi implementirali nekaj takega kot je borrow checker iz Rust? Ste ga gledali, kak\u0161no je va\u0161e mnenje o njem?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: No, \u017ee pi\u0161em v C \u017ee celo ve\u010dnost, s temi malloc in free, ter ro\u010dno upravljam \u017eivljenjsko dobo. Veste, 90-95 % ro\u010dno upravljane \u017eivljenjske dobe ima enako strukturo. In to je zelo, zelo bole\u010de ukvarjati se s tem ro\u010dno. Rad bi, da bi prevajalnik preprosto povedal, kaj se dogaja in \u010desa sem s svojimi dejanjimi dosegel. Za nekatere stvari to preverjanje zadol\u017eitev stori kar samodejno. Poleg tega mora avtomatsko \u010drpati informacije, vse razumeti in me niti ne obremeniti s potrebo po razlagi tega razumevanja. Mora izvesti vsaj lokalno analizo uhajanja, in \u0161ele \u010de mu to ne uspe, je treba dodati oznake tipov, ki bodo opisovale \u017eivljenjsko dobo \u2013 tak\u0161na shema je veliko zahtevnej\u0161a od preverjanja zadol\u017eitev, ali sploh katerega koli obstoje\u010dega preverjevalnika pomnilnika. Izbira med 'vse je v redu' in 'nisem ni\u010desar razumel' \u2014 ne, moralo bi biti kaj bolj\u0161ega.\u00a0<br \/>\nKot sem \u010dlovek, ki je napisal veliko kode v C, menim, da je podpora za samodejno upravljanje \u017eivljenjske dobe klju\u010dnega pomena. Poleg tega me moti, kako mo\u010dno Java uporablja pomnilnik, in moja glavna prito\u017eba je glede GC. Pri dodeljevanju pomnilnika v Javi ti ne vrne pomnilnika, ki je bil lokalno uporabljen v zadnjem ciklu GC. V jezikih z natan\u010dnej\u0161im upravljanjem pomnilnika to ni tako. Ko pokli\u010de\u0161 malloc, dobi\u0161 pomnilnik, ki je obi\u010dajno ravno bil uporabljen. Obi\u010dajno dela\u0161 z pomnilnikom kak\u0161ne za\u010dasne stvari in ga takoj vrne\u0161 nazaj. In takoj se vrne v pool malloc-a in naslednji klic malloc-a jo spet potegne ven. Zato se dejanska poraba pomnilnika zmanj\u0161a na nabor aktivnih objektov v dolo\u010denem trenutku, poleg pu\u0161\u010danj. In \u010de ne pu\u0161\u010da\u0161 pomnilnika na neprimeren na\u010din, se ve\u010dina pomnilnika usede v predpomnilnikih in procesorju, kar deluje hitro. Vendar zahteva veliko ro\u010dnega upravljanja pomnilnika z malloc in free, kjer mora\u0161 skrbeti za pravilno zaporedje in mesto klicanega. Rust to lahko sama pravilno upravlja in v mnogih primerih celo dose\u017ee ve\u010djo zmogljivost, saj se poraba pomnilnika zmanj\u0161uje le na trenutne izra\u010dune \u2013 nasproti pri\u010dakovanju naslednjega cikla GC, ki bo osvobodil pomnilnik. Na koncu smo dobili zelo zanimiv na\u010din za izbolj\u0161anje zmogljivosti. In precej mo\u010dno \u2013 v smislu, da sem se ukvarjal s tak\u0161nimi zadevami pri obdelavi podatkov za fintech, kar je omogo\u010dilo petkratno pospe\u0161itev. To je precej velika pospe\u0161itev, \u0161e posebej v svetu, kjer procesorji ne postajajo hitrej\u0161i, medtem ko \u0161e vedno \u010dakamo na izbolj\u0161ave.<\/p>\n<p><\/p>\n<h1 id=\"karera-performans-inzhenera\">Career of a performance engineer<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Rad bi \u0161e vpra\u0161al o karieri na splo\u0161no. Postali ste znani po delu na JIT v HotSpot, nato ste se preselili v Azul \u2013 in to je tudi podjetje, ki se ukvarja z JVM. Toda bolj ste se ukvarjali s strojno opremo kot s programsko opremo. Potem pa ste nenadoma pre\u0161li na Big Data in strojno u\u010denje, nato pa na odkrivanje goljufij. Kako je do tega pri\u0161lo? To so zelo razli\u010dna podro\u010dja razvoja.<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: \u017de dolgo se ukvarjam s programiranjem in sem se uspel izkazati na zelo razli\u010dnih podro\u010djih. In ko ljudje re\u010dejo: \u201eOh, ti si tisti, ki je naredil JIT za Javo!\u201c, je to vedno sme\u0161no. Pred tem sem se ukvarjal z klonom PostScript \u2013 jezika, ki ga je Apple neko\u010d uporabljal za svoje laserske tiskalnike. Pred tem sem delal implementacijo jezika Forth. Mislim, da je skupna tema zame razvoj orodij. Vse \u017eivljenje delam orodja, s katerimi drugi ljudje pi\u0161ejo svoje velike programe. A sem se ukvarjal tudi z razvojem operacijskih sistemov, gonilnikov, razhro\u0161\u010devalnikov nivoja jedra, jezikov za razvoj OS, ki so se sprva zdeli enostavni, a so skozi \u010das postajali vse bolj kompleksni. A glavna tema je vseeno \u2013 razvoj orodij. Velik del \u017eivljenja je minil med Azulom in Sunom, in to je bilo o Javi. A ko sem se za\u010del ukvarjati z Big Data in strojim u\u010denjem, sem znova oblekel svojo sve\u010dano \u010depico in rekel: \u201eOh, zdaj imamo nenavadno te\u017eavo, in tukaj se dogaja cela vrsta zanimivih stvari in ljudi, ki nekaj delajo.\u201c To je odli\u010dna pot za razvoj, po kateri se je vredno podati. <\/p>\n<p><\/p>\n<p>Da, zelo imam rad porazdeljene izra\u010dune. Moje prvo delo je bilo v \u0161tudentstvu na C, pri ogla\u0161evalski kampanji. To so bili porazdeljeni izra\u010duni na \u010dipih Zilog Z80, ki so zbirali podatke za analogno opti\u010dno prepoznavanje besedil, ki ga je izvajal pravi analogni analizator. Bila je zanimiva in povsem nenavadna tema. Vendar so se pojavile te\u017eave, nekateri deli niso bili pravilno prepoznani, zato je bilo treba zajeti sliko in jo pokazati osebi, ki jo je brala z o\u010dmi in poro\u010dala, kaj pi\u0161e, zato so bile naloge s podatki in te naloge so imele svoj jezik. Imeli smo backend, ki je vse to obdeloval \u2013 Z80, ki so delovali vzporedno z aktivnimi terminali vt100 \u2013 en za vsakega \u010dloveka, in imeli smo model vzporednega programiranja na Z80. Nek delovni spomin, ki so ga delili vsi Z80 znotraj konfiguracije tipa 'zvezda'; delila sta se tudi backplane in polovica RAM-a se je delila znotraj omre\u017eja, druga polovica pa je bila zasebna ali uporabljena za kaj drugega. Smiselno kompleksni vzporedni porazdeljeni sistem z deljenjem\u2026 polodeljenim spominom. Kdaj je to bilo\u2026 \u017de ne morem ve\u010d spomniti, nekje sredi 80-ih. Zelo dolgo nazaj.\u00a0<br \/>\nDa, lahko re\u010demo, da je 30 let dovolj dolgo. Naloge, povezane s porazdeljenimi izra\u010duni, obstajajo \u017ee dolgo, ljudje \u017ee od nekdaj se borijo s <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Beowulf_(%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80)\">Beowulf<\/a><\/noindex>-klasterji. Ti klasterji izgledajo kot... Na primer: obstaja Ethernet in tvoj hitri x86 je povezan s tem Ethernetom, in zdaj si \u017eeli\u0161 pridobiti fake shared memory, ker takrat nih\u010de ni mogel programirati razdeljenih izra\u010dunov, to je bilo preve\u010d zapleteno in zato je obstajala fake shared memory z za\u0161\u010dito strani pomnilnika na x86, in \u010de si pisal v to stran, smo drugim procesorjem sporo\u010dili, da \u010de pridobijo dostop do iste shared memory, jo morajo nalo\u017eiti od tebe, in tako se je pojavilo nekaj, kar je izgledalo kot protokol za podporo koherentnosti predpomnilnika in programske opreme za to. Zanimiva koncept. Prava te\u017eava pa je bila v drugem. Vse je delovalo, a kmalu si imel te\u017eave s hitrostjo, saj nih\u010de ni razumel modela zmogljivosti na dovolj dobri ravni \u2013 kak\u0161ni so tam vzorci dostopa do pomnilnika, kako poskrbeti, da se vozli\u0161\u010da neskon\u010dno ne pingajo med seboj, in tako naprej. <\/p>\n<p><\/p>\n<p>V H2O sem razvijalci sami odgovorni za to, da dolo\u010dijo, kje je prisoten paralelizem in kje ga ni. Ustvaril sem model kodiranja, pri katerem je pisanje visoko performantne kode enostavno in preprosto. Pisanje slabo delujo\u010de kode pa je zapleteno, tak\u0161na koda bo slabo izgledala. Potrebno se je resno potruditi, da napi\u0161e\u0161 po\u010dasi delujo\u010do kodo, uporaba nestandardnih metod je nujna. Kodo, ki upo\u010dasnjuje delovanje, je mogo\u010de opaziti \u017ee na prvi pogled. Posledi\u010dno se obi\u010dajno pi\u0161e koda, ki deluje hitro, vendar se morate ukvarjati s tem, kako ravnati v primeru deljene pomnilnika. Vse to je povezano z velikimi tabelami, njihovo delovanje pa je podobno nevolatilnim velikim tabelam v paralelni Javi. Predstavljajte si dva niti, ki pi\u0161eta v paralelno tabelo; ena zmaga, druga izgubi, ne veste pa, kdo je kdo. \u010ce nista volatilni, lahko red pride do kakr\u0161negakoli \u2013 in to res dobro deluje. Ljudje dejansko skrbijo za red operacij, pravilno postavijo volatile in na pravih mestih pri\u010dakujejo te\u017eave z zmogljivostjo, povezane s pomnilnikom. V nasprotnem primeru bi preprosto pisali kodo v obliki zank od 1 do N, kjer je N kak\u0161nih trilijonov, v upanju, da bodo vsi zahtevni primeri samodejno postali paralelni \u2013 kar pa ne deluje. A v H2O to ni Java, niti Scala, lahko bi rekli<\/p>\n<p><\/p>\n<h1 id=\"tehnicheskie-chellenzhi\">Technical challenges<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Kak\u0161en je bil va\u0161 najve\u010dji izziv v karieri?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ali razpravljamo o tehni\u010dnem ali ne tehni\u010dnem delu vpra\u0161anja? Rekel bi, da so najve\u010dji izzivi ne-tehni\u010dni.\u00a0<br \/>\nKar zadeva tehni\u010dne izzive. Preprosto sem jih premagal. Niti ne vem, kateri je bil najve\u010dji, a bilo je nekaj zelo zanimivih, pri katerih je bilo potrebnega kar precej \u010dasa in mentalne borbe. Ko sem \u0161el v Sun, sem bil prepri\u010dan, da bom naredil hiter prevajalnik, a vrsta starej\u0161ih je proti temu rekla, da mi nikoli ne bo uspelo. Vendar sem se odlo\u010dil, da bom \u0161el v to smer, napisal prevajalnik vse do dodeljevalnika registrov, in bil precej hiter. Bil je tako hiter kot sodobni C1, vendar je takrat dodeljevalnik deloval veliko po\u010dasneje, in ko gledam nazaj - to je bila te\u017eava velike podatkovne strukture. Potreboval sem jo, da napi\u0161em grafi\u010dni dodeljevalnik registrov in nisem razumel dilem med izrazitostjo kode in hitrostjo, ki sta obstajali v tistem \u010dasu in sta bili zelo pomembni. Izkazalo se je, da je podatkovna struktura obi\u010dajno ve\u010dja od velikosti predpomnilnika na x86 tistega \u010dasa, zato, \u010de sem sprva predvideval, da bo dodeljevalnik registrov porabil 5-10 odstotkov celotnega \u010dasa JIT, se je v resnici to izkazalo za 50 odstotkov. <\/p>\n<p><\/p>\n<p>\u010cas je mineval, prevajalnik je postal vse bolj jasen in zmogljiv, prenehal je generirati grozno kodo v ve\u010dini primerov, in zmogljivost je vse pogosteje za\u0161la v obmo\u010dje, ki ga je podal prevajalnik C. \u010ce seveda ne pi\u0161e\u0161 ne\u010desa slabega, kar niti C ne pospe\u0161i. \u010ce pi\u0161e\u0161 kodo, kot na C, dobi\u0161 tudi u\u010dinkovitost kot na C v ve\u010dini primerov. In \u010dedalje pogosteje je bila koda asimptotsko primerna s tisto na ravni C, dodeljevalnik registrov pa je za\u010del delovati kot kon\u010dna stvar\u2026 ne glede na to, ali tvoja koda deluje hitro ali po\u010dasi. Nadaljeval sem z delom na dodeljevalniku, da bi dobil bolj\u0161a dodeljevanja. Postal je vse po\u010dasnej\u0161i, a je omogo\u010dal vedno bolj\u0161o zmogljivost v primerih, kjer se nih\u010de drug ni zna\u0161el. Lahko sem se poglobil v dodeljevalnik registrov, vlo\u017eil mesec dela, in nenadoma se je vsa koda za\u010dela izvajati 5% hitreje. To se je dogajalo znova in znova in dodeljevalnik registrov je postal nekak\u0161no umetni\u0161ko delo \u2013 vsi so ga imeli radi ali ga sovra\u017eili, ljudje iz akademskega sveta pa so postavljali vpra\u0161anja o tem, zakaj je vse tako narejeno, zakaj ne. <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation#Linear_Scan\">linijska skeniranja<\/a><\/noindex>, in de waarom is het verschil. Het antwoord is hetzelfde: een allocator op basis van grafkleuring plus zeer nauwkeurige werkzaamheden met buffer-code gelijk aan een wapen van overwinning, de beste combinatie die niemand kan verslaan. En het is een behoorlijk onduidelijk iets. Alles wat de compiler daar verder doet, zijn vrij goed bestudeerde zaken, hoewel ze ook tot een kunstniveau zijn gebracht. Ik heb altijd dingen gedaan die de compiler in een kunstwerk moesten veranderen. Maar niets van dat alles was iets buitengewoons - behalve de register-allocator. De focus ligt in het feit dat je zorgvuldig <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation\">afsnijdt<\/a><\/noindex> onder belasting en, als dit gebeurt (ik kan het verder uitleggen als dat interessant is), betekent dit dat je agressiever kunt inlineen, zonder het risico te lopen over de prestatiegrafiek heen te gaan. In die tijd waren er veel volledig uitgeruste compilers, vol met franje en toeters, waarin register-allocators zaten, maar niemand kon dat nog meer. <\/p>\n<p><\/p>\n<p>Te\u017eava je v tem, da, \u010de doda\u0161 metode, ki jih je mogo\u010de inlineati, pove\u010duje\u0161 in pove\u010duje\u0161 podro\u010dje inlineanja, se niz uporabljenih vrednosti takoj pove\u010da nad \u0161tevilo registrov, kar povzro\u010di spill. Kriti\u010dna meja ponavadi nastopi, ko se alokator predaja, in en dober kandidat za spill stane drugega, ti spill\u0161 nekak\u0161ne povsem nenavadne stvari. Vrednost inlineanja tukaj je v tem, da izgubi\u0161 del overheada, overheada na klic in shranjevanje, lahko vidi\u0161 vrednosti znotraj in jih lahko dodatno optimizira\u0161. Stro\u0161ki inlineanja pa so v tem, da se ustvari veliko \u017eivih vrednosti, in \u010de tvoj alokator registrov spilla ve\u010d, kot je potrebno, takoj izgubi\u0161. Zato ima ve\u010dina alokatorjev te\u017eavo: ko inlineanje preide dolo\u010deno mejo, za\u010dne spillati vse na svetu in zmogljivost se lahko spere stran. Tisti, ki razvijajo prevajalnik, dodajajo nekatere heuristike: na primer, da ustavijo inlineanje, ko dose\u017ee dovolj veliko velikost, saj alokacije vse pokvarijo. Tako se pojavi zlom grafikon zmogljivosti \u2013 inline\u0161, inline\u0161, zmogljivost po\u010dasi raste \u2013 in nato bum! \u2013 pade hitro, ker si inlineal preve\u010d. Tako je vse delovalo do prihoda Jave. Java zahteva precej ve\u010d inlineanja, zato sem moral svoj alokator narediti veliko bolj agresiven, da se izravna, namesto da pade, in \u010de si preve\u010d inlineal \u2013 za\u010dne spillati, a nato vseeno pride trenutek, ko 'ni ve\u010d spillanja'. To je zanimivo spoznanje in pri\u0161lo je do mene kar iz ni\u010d, ni o\u010ditno, a se je dobro obrestovalo. Lotil sem se agresivnega inlineanja in to me je pripeljalo na podro\u010dja, kjer sta zmogljivost Jave in C blizu jedna drugi. Resni\u010dno sta si blizu \u2013 lahko pi\u0161em kodo v Javi, ki je precej hitrej\u0161a od kode v C in podobno, a povpre\u010dno, v veliki sliki stvari, sta si pribli\u017eno enaki. Zdi se, da je del te zasluge alokator registrov, ki mi omogo\u010da, da inlineam kar se da naivno. Simply inlineam vse, kar vidim. Vpra\u0161anje pa je, ali alokator deluje dobro, ali dobi\u0161 razumljivo delujo\u010do kodo. To je bil velik izziv: razumeti vse to in ga spraviti v delovanje.<\/p>\n<p><\/p>\n<h1 id=\"nemnogo-pro-allokaciyu-registrov-i-mnogoyadernost\">A bit about register allocation and multithreading<\/h1>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Te\u017eave, kot je dodelitev registrov, se zdijo neskon\u010dna tema. Zanimivo bi bilo vedeti, ali je bila kdaj neka ideja obetavna, a je kasneje v praksi propadla?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Seveda! Dodelitev registrov je podro\u010dje, kjer se pri re\u0161evanju NP-polne naloge trudite najti nekatere heuristicne pristope. In nikoli ne morete dose\u010di popolne re\u0161itve, kajne? To je preprosto nemogo\u010de. Poglejte, predkompilacija \u2013 tudi ta slabo deluje. Tukaj gre za neke povpre\u010dne primere. O tipi\u010dni zmogljivosti, tako da lahko greste meriti nekaj, kar menite, da je dobra tipi\u010dna zmogljivost \u2013 na koncu koncev, delate na njenem izbolj\u0161anju! Dodelitev registrov je tema, ki je v celoti posve\u010dena zmogljivosti. Takoj ko imate prvi prototip, ki deluje in barva tisto, kar mora, se za\u010dnejo dela na zmogljivosti. Nau\u010diti se morate dobro meriti. Zakaj je to pomembno? \u010ce so na voljo jasni podatki, lahko pogledate na razli\u010dna podro\u010dja in vidite: aha, to je tukaj pomagalo, a tukaj se je vse podrl! Pojavijo se dobre ideje, dodate novo heuristiko in nenadoma vse za\u010dne delovati povpre\u010dno nekoliko bolje. Ali pa ne. Imel sem veliko primerov, ko smo se borili za pet odstotkov zmogljivosti, ki so na\u0161o re\u0161itev lo\u010devala od prej\u0161njega dodeljevanja. In vsaki\u010d to izgleda tako: kje ste zmagali, kje izgubili. \u010ce imate dobre analiti\u010dne instrumente zmogljivosti, lahko najdete pora\u017eene ideje in razumete, zakaj so izgubile. Mogo\u010de je bolje pustiti stvari tak\u0161ne, kot so, ali pa se resneje lotiti fine nastavitve, ali pa iti in popraviti nekaj drugega. To je cel sklop stvari! Naredil sem ta odli\u010den trik, a potrebujem \u0161e tega, tega in tega \u2013 in njihova skupna kombinacija prina\u0161a dolo\u010dene izbolj\u0161ave. Posamezne ideje lahko propadejo. Tak\u0161na je narava dela na NP-polnih nalogah.<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Zdi se, da so stvari, kot so barvanje v dodeljevanju, \u017ee re\u0161ene naloge. No, za vas so po tem, kar pripovedujete, a se sploh spla\u010da\u2026<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ni se rije\u0161i sama od sebe. Ti to mora\u0161 pretvoriti u \u00abrije\u0161eno\u00bb. Postoje te\u0161ki zadaci i njih treba rije\u0161iti. Kada se to u\u010dini, dolazi vrijeme za rad na performansama. Na tu se zada\u0107u treba pristupiti odgovaraju\u0107e \u2013 raditi benchmarke, prikupljati mjere, obja\u0161njavati situacije kada se povratkom na prethodnu verziju tvoj stari haker ponovno aktivira (ili obrnuto, prestane raditi). I ne odustati dok ne postigne\u0161 ne\u0161to. Kao \u0161to sam ve\u0107 rekao, ako su cool ideje koje nisu uspjele, u podru\u010dju alokacije registara ideja je otprilike beskona\u010dno mnogo. Na primjer, mo\u017ee\u0161 \u010ditati znanstvene radove. Iako je to podru\u010dje sada postalo sporije i jasnije nego u vrijeme svoje mladosti. Ipak, u tom podru\u010dju radi cijela beskona\u010dnost ljudi i sve njihove ideje vrijedi isprobati, sve \u010dekaju svoj trenutak. I ne mo\u017ee\u0161 re\u0107i koliko su dobre ako ih ne proba\u0161. Koliko se dobro integriraju s ostalim dijelovima tvoje alokacije, jer alokator radi mnoge stvari, i neke ideje u tvom specifi\u010dnom alokatoru ne\u0107e raditi, dok u drugom alokatoru lako mogu. Glavni na\u010din pobjede za alokator je izvu\u0107i sporu stvar iz glavne staze i prisiliti je na razdvajanje po granicama sporih staza. Zato, ako \u017eeli\u0161 pokrenuti GC, i\u0107i sporom stazom, deoptimizirati se, baciti iznimku, sve u tom smislu \u2013 zna\u0161 da su te stvari relativno rijetke. I zaista su rijetke, provjeravao sam. \u010cini\u0161 dodatni rad i zbog toga nestaje mnogo ograni\u010denja na tim sporim stazama, ali to nije isuvi\u0161e va\u017eno, jer su spore i rijetko ih koriste. Na primjer, nulti pokaziva\u010d \u2013 on se nikada ne doga\u0111a, zar ne? Treba imati nekoliko staza za razli\u010dite stvari, ali se ne bi trebale mije\u0161ati na glavnom.\u00a0<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: \u0160to mislite o vi\u0161ekontrolernoj obradi, kada odmah ima\u0161 tisu\u0107e jezgri? Je li to korisna stvar?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Uspjeh GPU-a pokazuje da je prili\u010dno korisno!<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Oni su prili\u010dno specijalizirani. A \u0161to je s procesorima op\u0107e namjene?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: No, to je bila poslovna modela Azul. Odgovor je do\u0161ao jo\u0161 u eri kada su ljudi jako voljeli predvidivu performansu. Tada je bilo te\u0161ko pisati paralelni kod. H2O model kodiranja se dobro skalira, ali nije model op\u0107e namjene. Mo\u017eda je malo op\u0107enitiji od kori\u0161tenja GPU-a. Govorimo o slo\u017eenosti razvoja takve stvari ili o slo\u017eenosti njezine upotrebe? Na primjer, zanimljiva lekcija koju mi je dala Azul, prili\u010dno ne o\u010digledna: mali ke\u0161evi su u redu.\u00a0<\/p>\n<p><\/p>\n<h1 id=\"samyy-bolshoy-chellenzh-v-zhizni\">The biggest challenge in life<\/h1>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: \u0160to je s netehni\u010dkim izazovima?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Najve\u010dji izziv je bil ne biti... prijazen in dober do ljudi. Kot posledica sem se nenehno nahajal v izjemno konfliktnih situacijah. V tak\u0161nih, kjer sem vedel, da stvari ne gredo prav, a nisem vedel, kako napredovati pri re\u0161evanju teh te\u017eav in se z njimi spoprijeti. \u0160tevilne dolgoletne te\u017eave, ki so trajale desetletja, so se pojavile prav na ta na\u010din. To, da v Javi obstajata kompilatorja C1 in C2, je neposredna posledica tega. Da v Javi ve\u010d kot deset let ni bilo ve\u010dstopenjske kompilacije, je prav tako neposredna posledica. O\u010ditno smo potrebovali tak sistem, a ni jasno, zakaj ga ni bilo. Imel sem te\u017eave z enim in\u017eenirjem... ali skupino in\u017eenirjev. Pred davnimi \u010dasi, ko sem za\u010del delati v Sunu, sem bil... No, ne samo takrat, vedno imam svoje mnenje o vsem. In verjel sem, da lahko preprosto vzamem to svojo resnico in jo povem naravnost. \u0160e posebej, ker sem bil velikokrat \u0161okantno prav. In \u010de ti ta pristop ni v\u0161e\u010d... \u0161e posebej, \u010de si o\u010ditno v zmoti in dela\u0161 neumnosti... Na splo\u0161no je le redko kdo lahko prena\u0161al to obliko komunikacije. \u010ceprav so nekateri, recimo, jaz. Celotno \u017eivljenje sem gradil na meritokrati\u010dnih na\u010delih. \u010ce mi poka\u017eete nekaj narobe, se takoj obrnem in re\u010dem: rekel si neumnost. Pri tem se seveda opravi\u010dim in vse to, priznam zasluge, \u010de te sploh imate, in opravim druge pravilne korake. Po drugi strani pa sem \u0161okantno prav v \u0161okantno velikem odstotku skupnega \u010dasa. In to ne deluje najbolje v odnosih z ljudmi. Ne trudim se biti prijazen, ampak postavljam vpra\u0161anje na jasno. 'To nikoli ne bo delovalo, ker en, dva in tri.' In oni: 'Oh!'. Bile so tudi druge posledice, ki jih je bolje verjetno presko\u010diti: na primer, ki so pripeljale do lo\u010ditve z \u017eeno in desetletja depresije po tem.<\/p>\n<p><\/p>\n<p>Izziv je boj s ljudmi in njihovim dojemanjem tega, kar lahko ali ne more\u0161 po\u010deti, kar je pomembno in kar ni. Bilo je veliko izzivov glede sloga kodiranja. \u0160e vedno pi\u0161em veliko kode, a v tistih \u010dasih sem se moral celo upo\u010dasniti, ker sem delal preve\u010d nalog hkrati in sem jih opravljal slabo, namesto da bi se osredoto\u010dil na eno samo nalogo. Ko gledam nazaj, sem napisal polovico kode ekipe Java JIT, ekipe C2. Naslednji najhitrej\u0161i kodir je pisal polovico po\u010dasneje, naslednji \u0161e enkrat po\u010dasneje in to je bil eksponenten upad. Sedmi \u010dlovek v vrsti je bil zelo, zelo po\u010dasen \u2013 tako je vedno! Dotaknil sem se kup kode. Gledal sem, kdo kaj pi\u0161e, brez izjem, buljil sem v njihovo kodo, pregledoval vsakega od njih, in kljub temu \u0161e vedno pisal ve\u010d kot kdorkoli od njih. Z ljudmi tak\u0161en pristop ni preve\u010d uspe\u0161en. Nekaterim to ni v\u0161e\u010d. In ko se s tem ne morejo soo\u010diti, se za\u010dnejo razli\u010dne prito\u017ebe. Na primer, enkrat so mi rekli, da naj preneham pisati kodo, ker pi\u0161em preve\u010d kode in to ogro\u017ea ekipo, in za mene je to zvenelo kot \u0161ala: ej, \u010de bo celotna preostala ekipa izginila in bom jaz \u0161e naprej pisal kodo, bo\u0161 izgubil samo polovico ekipe. Po drugi strani, \u010de bom \u0161e naprej pisal kodo in bo\u0161 izgubil polovico ekipe \u2013 zveni kot zelo slabo vodenje. Nikoli se nisem pretirano spra\u0161eval o tem, nikoli o tem govoril, a je kljub temu bilo nekje v moji glavi. V ozadju zavesti je kro\u017eila misel: \u201eAli ste vsi res resni?\u201c Tako da je bila najve\u010dja te\u017eava jaz in moje odnose z ljudmi. Zdaj se mnogo bolj razumem, dolgo sem bil tim lider med programerji in zdaj ljudem odprto povem: ve\u0161, tak\u0161en sem, kot sem, in morali se boste spoprijeti z mano \u2013 ali je v redu, \u010de tukaj malo stojim? In ko so se s tem nau\u010dili spoprijeti, je vse za\u010delo delovati. Namre\u010d, nisem ne slab ne dober, nimam slabih namenov ali egoisti\u010dnih te\u017eav, to je le moja narava in nekako se je potrebno s tem spoprijeti.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Pred kratkim je bilo veliko govora o samospoznanju za introverte in sploh o mehkih spretnostih. Kaj bi se o tem dalo povedati?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ja, to by\u0142o zrozumienie i lekcja, kt\u00f3r\u0105 wynios\u0142em z rozwodu z \u017con\u0105. Czego si\u0119 nauczy\u0142em z rozwodu \u2013 to zrozumienie samego siebie. Tak zacz\u0105\u0142em rozumie\u0107 innych ludzi. Rozumie\u0107, jak dzia\u0142a ta interakcja. To doprowadzi\u0142o do odkry\u0107 jedno po drugim. Pojawi\u0142a si\u0119 \u015bwiadomo\u015b\u0107, kim jestem i co sob\u0105 reprezentuj\u0119. Co robi\u0119: albo skupiam si\u0119 na zadaniu, albo unikam konfliktu, albo co\u015b innego \u2013 a taki poziom samo\u015bwiadomo\u015bci naprawd\u0119 pomaga utrzyma\u0107 si\u0119 w ryzach. Po tym wszystkim wszystko staje si\u0119 prostsze. Jedna rzecz, kt\u00f3r\u0105 odkry\u0142em nie tylko u siebie, ale i u innych programist\u00f3w \u2013 to niemo\u017cno\u015b\u0107 werbalizacji my\u015bli, kiedy jeste\u015b w stanie stresu emocjonalnego. Na przyk\u0142ad, siedzisz, kodujesz, jeste\u015b w stanie przep\u0142ywu, a tu podbiegaj\u0105 do ciebie i zaczynaj\u0105 krzycze\u0107 w histerii, \u017ce co\u015b si\u0119 zepsu\u0142o, i teraz b\u0119d\u0105 zastosowane skrajne \u015brodki. I nie mo\u017cesz wydusi\u0107 ani s\u0142owa, bo jeste\u015b w stanie emocjonalnego stresu. Nabyte umiej\u0119tno\u015bci pozwalaj\u0105 przygotowa\u0107 si\u0119 na ten moment, prze\u017cy\u0107 go i przej\u015b\u0107 do planu wycofania, po kt\u00f3rym mo\u017cna ju\u017c co\u015b zrobi\u0107. Wi\u0119c tak, kiedy zaczynasz zdawa\u0107 sobie spraw\u0119, jak to wszystko dzia\u0142a \u2013 to ogromne, \u017cyciowe wydarzenie.\u00a0<br \/>\nSam nie potrafi\u0142em znale\u017a\u0107 odpowiednich s\u0142\u00f3w, ale zapami\u0119ta\u0142em ci\u0105g dzia\u0142a\u0144. Istota jest taka, \u017ce ta reakcja jest tak samo fizyczna, jak i werbalna, i potrzebujesz przestrzeni. Takiej przestrzeni, w zenowym sensie. W\u0142a\u015bnie to trzeba wyja\u015bni\u0107, a potem od razu si\u0119 cofn\u0105\u0107 \u2013 czysto fizycznie si\u0119 cofn\u0105\u0107. Kiedy milcz\u0119 s\u0142owami, mog\u0119 przetworzy\u0107 sytuacj\u0119 w cz\u0119\u015bci emocjonalnej. Kiedy adrenalina dociera do m\u00f3zgu, prze\u0142\u0105cza ci\u0119 w tryb \u201ewalcz lub uciekaj\u201d, ju\u017c nie mo\u017cesz nic powiedzie\u0107, nie \u2013 teraz jeste\u015b idiot\u0105, in\u017cynierem do bicia, niezdolnym do godnej odpowiedzi czy przynajmniej do zatrzymania ataku, a atakuj\u0105cy mo\u017ce swobodnie zaatakowa\u0107 znowu i znowu. Najpierw musisz zn\u00f3w sta\u0107 si\u0119 sob\u0105, odzyska\u0107 kontrol\u0119, wyj\u015b\u0107 z trybu \u201ewalcz lub uciekaj\u201d. <\/p>\n<p><\/p>\n<p>In order to achieve this, a verbal space is necessary. Just a free space. If you are going to say something, you might as well state this and then go and really find yourself a 'space': take a walk in the park, lock yourself in the shower \u2013 it doesn't matter. The main thing is to temporarily disconnect from the situation. As soon as you disconnect for at least a few seconds, control returns, and you start to think clearly. 'Okay, I'm not some idiot; I'm not doing stupid things; I'm a fairly useful person.' Once you manage to convince yourself, it's time to move on to the next step: to understand what happened. You were attacked, the attack came unexpectedly, it was an unfair, sneaky ambush. That\u2019s bad. The next step is to understand why the attacker needed this. Really, why? Maybe because he is furious himself? Why is he furious? For instance, because he messed up and cannot take responsibility? This is how you need to carefully process the whole situation. But for that, you need space to maneuver, a verbal space. The very first step is to break the verbal contact. Move away from the discussion verbally. Cancel it, leave as quickly as possible. If it's a phone call \u2013 just hang up \u2013 it's a skill I learned from communicating with my ex-wife. If the conversation is leading nowhere good, just say 'goodbye' and hang up. On the other end of the line: 'blah-blah-blah', you respond: 'uh-huh, bye!' and hang up. You just cut off the conversation. Five minutes later, when your ability to think clearly returns, you have cooled down a bit, and it becomes possible to consider what actually happened and what to do next. And start formulating a thoughtful response rather than just reacting on emotion. For me, a breakthrough in self-awareness was realizing that in the case of emotional stress, I cannot speak. Getting out of that state, thinking over and planning how to respond and address the problems \u2013 those are the right steps when you cannot talk. The easiest way is to run away from the situation that manifests emotional stress and simply stop participating in that stress. After that, you regain the ability to think, when you can think, the ability to speak arises, and so on.<\/p>\n<p><\/p>\n<p>Poleg tega, v sodnem postopku odvetnik nasprotne strani sku\u0161a to narediti s tabo \u2013 zdaj je \u017ee jasno, zakaj. Ker ima mo\u017enost, da te potla\u010di do takega stanja, da ne more\u0161 niti izgovoriti svojega imena. V dobesednem pomenu, ne more\u0161 govoriti. \u010ce se ti to dogaja in \u010de ve\u0161, da se bo\u0161 zna\u0161el na mestu, kjer se odvijajo verbalne bitke, na mestu, kot je sodi\u0161\u010de, lahko pride\u0161 s svojim odvetnikom. Odvetnik te bo zagovarjal in ustavil verbalni napad, in to bo storil na povsem zakonit na\u010din, in vrnilo se ti bo izgubljeno zenovsko prostor. Na primer, nekajkrat sem moral poklicati dru\u017eino, sodnik je nanje gledal povsem prijazno, medtem ko je odvetnik nasprotne strani kri\u010dal name in sem se celo moral zadr\u017eati, da sem lahko vtaknil besedo. V takih primerih se zame najbolje obnese uporaba posrednika. Posrednik prekine vso to nenehno obremenitev, ki te pritisne s neprekinjenim tokom, odkriva\u0161 potrebno zenovsko prostor, skupaj s tem se vrne sposobnost govora. To je celo podro\u010dje znanja, kjer se je treba veliko nau\u010diti, veliko odkriti v sebi, in vse to se pretvori v visoko kakovostne strate\u0161ke odlo\u010ditve, ki so razli\u010dne za razli\u010dne ljudi. Nekateri nimajo zgoraj opisanih te\u017eav, obi\u010dajno jih nimajo ljudje, ki se profesionalno ukvarjajo s prodajo. Vsi ti ljudje, ki si slu\u017eijo kruh z besedami \u2013 znani pevci, pesniki, religiozni voditelji in politiki, imajo vedno kaj povedati. Nimajo takih te\u017eav, jaz pa jih imam.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: To je bilo \u2026 presenetljivo. Odli\u010dno, \u017ee smo precej govorili in \u010das je, da zaklju\u010dimo to intervju. Obvezno se sre\u010damo na konferenci in lahko nadaljujemo ta dialog. Se vidimo na Hydri!<\/p>\n<p><\/p>\n<blockquote><p>Nadaljevati komunikacijo s Cliffom bo mogo\u010de na konferenci Hydra 2019, ki bo potekala 11.-12. julija 2019 v Sankt Peterburgu. Pri\u0161el bo s predstavitvijo <noindex><a rel=\"nofollow\" href=\"https:\/\/hydraconf.com\/2019\/talks\/2jix5mst7iduyp9linqhfj\/?utm_source=habr&amp;utm_medium=45871\">\u201eIzku\u0161nja Azul Hardware Transactional Memory\u201c<\/a><\/noindex>. Vstopnice je mogo\u010de kupiti <noindex><a rel=\"nofollow\" href=\"https:\/\/hydraconf.ru\/?utm_source=habr&amp;utm_medium=458718\">on the official website<\/a><\/noindex>.<\/p><\/blockquote>\n<p>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/jugru\/blog\/458718\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041a\u043b\u0438\u0444\u0444 \u041a\u043b\u0438\u043a \u2014 CTO \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Cratus (IoT \u0441\u0435\u043d\u0441\u043e\u0440\u044b \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432), \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438 \u0441\u043e\u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0430\u0440\u0442\u0430\u043f\u043e\u0432 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f Rocket Realtime School, Neurensic \u0438 H2O.ai) \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c\u0438 \u044d\u043a\u0437\u0438\u0442\u0430\u043c\u0438. \u041a\u043b\u0438\u0444\u0444 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432 15 \u043b\u0435\u0442 (Pascal \u0434\u043b\u044f TRS Z-80)! \u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0434 \u04212 \u0432 Java (the Sea of Nodes IR). \u042d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u043a\u0430\u0437\u0430\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35851","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.5 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041a\u043b\u0438\u0444\u0444 \u041a\u043b\u0438\u043a \u2014.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.5\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0411\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0432\u044c\u044e \u0441 \u041a\u043b\u0438\u0444\u0444\u043e\u043c \u041a\u043b\u0438\u043a\u043e\u043c \u2014 \u043e\u0442\u0446\u043e\u043c JIT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 Java | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041a\u043b\u0438\u0444\u0444 \u041a\u043b\u0438\u043a \u2014.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:07:03+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:07:03+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Obse\u017eno intervju s Cliffom Clickom \u2014 o\u010detom JIT-kompilacije v Javi | ProHoster","description":"Cliff Click \u2014.","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0411\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0432\u044c\u044e \u0441 \u041a\u043b\u0438\u0444\u0444\u043e\u043c \u041a\u043b\u0438\u043a\u043e\u043c \u2014 \u043e\u0442\u0446\u043e\u043c JIT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 Java | ProHoster","og:description":"\u041a\u043b\u0438\u0444\u0444 \u041a\u043b\u0438\u043a \u2014.","og:url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:07:03+00:00","article:modified_time":"2019-10-31T19:07:03+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35851","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 01:01:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:55:25","updated":"2026-01-22 01:01:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/35851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=35851"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/35851\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=35851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=35851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=35851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}