{"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\/no\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","title":{"rendered":"Stort intervju med Cliff Click \u2013 faren til JIT-kompilering i Java","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Stort intervju med Cliff Click \u2013 faren til JIT-kompilering i Java\" 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 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 showed the world that JIT could produce quality code, which contributed to Java becoming one of the key modern software platforms. Later, Cliff helped Azul Systems build an 864-core mainframe running pure Java software that supported GC pauses on a 500-gigabyte heap within 10 milliseconds. Overall, Cliff has managed to work on all aspects of the JVM.<br clear=\"all\"><br \/>\n\u00a0<br \/>\nThis Hub post 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 do a 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 little 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>Andrei Sataryn<\/strong> from Amazon Web Services. Throughout his career, he has worked on a variety of projects: testing the 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. He is interested in testing large-scale backend and distributed systems.<\/li>\n<li><strong>Vladimir Sitnikov<\/strong> from Netcracker. For ten years, he has been working on the performance and scalability of NetCracker OS \u2014 software used by telecom operators to automate network management processes and network equipment. He is passionate about the performance of Java and Oracle Database. The 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>Andrei<\/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>: That's right!<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Let's start with general questions about working on performance. What do you think about the choice between high-level and low-level optimizations such as working at the CPU level?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Her er alt enkelt. Den raskeste koden er den som aldri kj\u00f8res. Derfor m\u00e5 man alltid starte p\u00e5 et h\u00f8yt niv\u00e5 og jobbe med algoritmer. En bedre O-notasjon vil sl\u00e5 en d\u00e5rligere O-notasjon, med mindre det kommer inn store konstanter. Lavniv\u00e5ting kommer alltid sist. Som regel, hvis du har optimalisert hele resten av stakken godt, og det fortsatt er noe interessant igjen \u2013 s\u00e5 er det lavt niv\u00e5. Men hvordan begynner du p\u00e5 et h\u00f8yt niv\u00e5? Hvordan vet du at du har gjort nok arbeid p\u00e5 h\u00f8yt niv\u00e5? Vel... ingen m\u00e5te. Det finnes ingen ferdige oppskrifter. Du m\u00e5 forst\u00e5 problemet, bestemme deg for hva du skal gj\u00f8re (for ikke \u00e5 ta un\u00f8dvendige skritt senere), og s\u00e5 kan du ta frem profilereren som kan si noe nyttig. P\u00e5 et tidspunkt forst\u00e5r du selv at du har blitt kvitt un\u00f8dvendige ting, og det er p\u00e5 tide \u00e5 ta for seg finjusteringen p\u00e5 lavt niv\u00e5. Dette er definitivt en spesiell type kunst. Mange mennesker gj\u00f8r un\u00f8dvendige ting, men de jobber s\u00e5 raskt at de ikke har tid til \u00e5 tenke p\u00e5 ytelse. Men det varer til sp\u00f8rsm\u00e5let blir presserende. Vanligvis er 99% av tiden ingen interessert i hva jeg driver med, helt til et viktig element dukker opp p\u00e5 den kritiske veien, som noen bryr seg om. Og s\u00e5 begynner alle \u00e5 sp\u00f8rre hvorfor det ikke fungerte perfekt fra starten av. Generelt sett er det alltid noe \u00e5 forbedre i ytelsen. Men 99% av tiden har du ikke ledetr\u00e5der! Du pr\u00f8ver bare \u00e5 f\u00e5 noe til \u00e5 fungere, og i l\u00f8pet av det forst\u00e5r du hva som er viktig. Du kan aldri vite p\u00e5 forh\u00e5nd at denne biten m\u00e5 v\u00e6re perfekt, s\u00e5 i bunn og grunn m\u00e5 du v\u00e6re perfekt i alt. Og det er umulig, og du gj\u00f8r ikke det. Det er alltid masse ting \u00e5 fikse \u2013 og det er helt normalt.<\/p>\n<p><\/p>\n<h1 id=\"kak-delat-bolshoy-refaktoring\">How to do a large refactoring<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Hvordan jobber du med ytelsen? Dette er jo et gjennomg\u00e5ende problem. Har du for eksempel noen gang jobbet med problemer som oppst\u00e5r p\u00e5 grunn av overlappingen av mye eksisterende funksjonalitet?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Jeg pr\u00f8ver \u00e5 unng\u00e5 det. Hvis jeg vet at ytelsen vil bli et problem, begynner jeg \u00e5 tenke f\u00f8r jeg begynner \u00e5 kode, spesielt p\u00e5 datakonstruksjoner. Men ofte oppdager du alt dette senere. Og da m\u00e5 man ta ekstreme tiltak og gj\u00f8re det jeg kaller \u00abomtale og hersk\u00bb: man m\u00e5 ta tak i et stort nok stykke. En del av koden m\u00e5 uansett skrives om p\u00e5 grunn av ytelsesproblemer eller av andre \u00e5rsaker. Hva grunnen til omskrivning av koden m\u00e5tte v\u00e6re, er det nesten alltid bedre \u00e5 skrive om et st\u00f8rre stykke enn et mindre stykke. P\u00e5 dette tidspunktet begynner alle \u00e5 skjelve av frykt: \u00ab\u00c5h nei, vi kan ikke r\u00f8re s\u00e5 mye kode!\u00bb. Men i virkeligheten fungerer denne tiln\u00e6rmingen nesten alltid mye bedre. Man m\u00e5 umiddelbart ta tak i et stort problem, omringe det med en stor sirkel og si: alt som er inne i sirkelen, vil jeg skrive om. Grensen er mye mindre enn innholdet inni den som skal byttes ut. Og hvis en slik avgrensning gj\u00f8r at arbeidet inni blir perfekt \u2013 har du frie hender, gj\u00f8r hva du vil. S\u00e5 snart du har forst\u00e5tt problemet, g\u00e5r omskrivingsprosessen mye enklere, s\u00e5 ta en stor bit!<br \/>\nSamtidig, n\u00e5r du gj\u00f8r en omskrivning av store mengder og forst\u00e5r at ytelse vil bli et problem, kan du begynne \u00e5 bekymre deg for det med en gang. Vanligvis ender det opp med enkle ting som \u00abikke kopier data, h\u00e5ndter data p\u00e5 en s\u00e5 enkel m\u00e5te som mulig, gj\u00f8r dem mindre\u00bb. I store omskrivninger er det standardmetoder for \u00e5 forbedre ytelsen. Og de dreier seg nesten alltid om data.<\/p>\n<p><\/p>\n<h1 id=\"model-stoimosti\">Cost model<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: I en av podcastene deres snakket dere om kostnadsmodeller i forhold til ytelse. Kan dere forklare hva som ment med det?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Selvf\u00f8lgelig. Jeg ble f\u00f8dt i en tid hvor prosessorens ytelse var ekstremt viktig. Og denne \u00e6raen er tilbake igjen \u2013 skjebnen er ikke uten ironi. Jeg begynte \u00e5 leve i en tid med \u00e5tte-bits maskiner, min f\u00f8rste datamaskin arbeidet med 256 bytes. Bare bytes. Alt var veldig lite. Det var n\u00f8dvendig \u00e5 telle instruksjoner, og s\u00e5 snart vi begynte \u00e5 bevege oss oppover i stakken av programmeringsspr\u00e5k, tok spr\u00e5kene p\u00e5 seg mer og mer. Det var Assembly, s\u00e5 Basic, s\u00e5 C, og C h\u00e5ndterte mange detaljer, som registerallokering og instruksjonsvalg. Men alt var ganske forst\u00e5elig, og hvis jeg laget en peker til en variabelinstans, fikk jeg en load, og kostnaden for denne instruksjonen er kjent. Maskinvaren gir et kjent antall maskinsykluser, s\u00e5 hastigheten p\u00e5 forskjellige operasjoner kan beregnes ved enkelt \u00e5 summere opp alle instruksjonene du har tenkt \u00e5 kj\u00f8re. Hver compare\/test\/branch\/call\/load\/store kunne legges sammen, og man kunne si: her er kj\u00f8retiden. N\u00e5r man jobber med \u00e5 forbedre ytelsen, vil man definitivt legge merke til hva tallene tilsvarer sm\u00e5, varme sl\u00f8yfer.\u00a0<br \/>\nMen s\u00e5 snart du bytter over til Java, Python og lignende ting, fjerner du deg veldig raskt fra lavniv\u00e5maskinvaren. Hva er kostnaden for \u00e5 kalle en getter i Java? Hvis JIT i HotSpot gj\u00f8r alt riktig, <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.openjdk.java.net\/display\/HotSpot\/Inlining\">inlinet<\/a><\/noindex>, vil det v\u00e6re en load, men hvis det ikke skjer \u2013 vil det v\u00e6re et funskjonskall. Siden kallet ligger p\u00e5 den varme sl\u00f8yfen, vil det oppheve alle andre optimaliseringer i denne sl\u00f8yfen. S\u00e5 den reelle kostnaden vil v\u00e6re mye h\u00f8yere. Og man mister umiddelbart evnen til \u00e5 se p\u00e5 en kodebit og forst\u00e5 at det ville v\u00e6rt verdt \u00e5 utf\u00f8re det i termer av prosessorens klokkefrekvens, brukt minne og cache. Alt dette blir interessant f\u00f8rst n\u00e5r man virkelig graver ned i ytelsen.<br \/>\nVi har n\u00e5dd et punkt der prosessorhastighetene knapt har \u00f8kt p\u00e5 ti \u00e5r. De gode gamle tidene er tilbake! Du kan ikke lenger forvente god ytelse i en enkelt tr\u00e5d. Men hvis man begynner med parallellbehandling \u2013 det er ekstremt komplisert, folk ser p\u00e5 deg som om du er James Bond. Ti ganger hastighets\u00f8kning skjer vanligvis der noen har oversett noe. Parallellitet krever mye arbeid. For \u00e5 oppn\u00e5 den nevnte ti ganger hastighets\u00f8kningen m\u00e5 man forst\u00e5 kostnadsmodellen. Hva koster hva. Og for \u00e5 gj\u00f8re det, m\u00e5 man forst\u00e5 hvordan spr\u00e5ket passer med maskinvaren.<br \/>\nMartin Thompson fant et utmerket ord for bloggen sin <noindex><a rel=\"nofollow\" href=\"https:\/\/mechanical-sympathy.blogspot.com\/\">Mechanical Sympathy<\/a><\/noindex>! Man m\u00e5 forst\u00e5 hva maskinvaren skal gj\u00f8re, hvordan den skal gj\u00f8re det, og hvorfor den gj\u00f8r det den gj\u00f8r. Ved \u00e5 bruke denne kunnskapen er det ganske enkelt \u00e5 begynne \u00e5 telle instruksjoner og finne ut hvor tiden g\u00e5r tapt. Hvis du ikke har passende oppl\u00e6ring, s\u00f8ker du bare etter en svart katt i et m\u00f8rkt rom. Jeg ser hele tiden folk som optimaliserer ytelse uten \u00e5 ha den minste anelse om hva de driver med. De sliter kraftig og kommer seg ikke noe sted. N\u00e5r jeg tar den samme koden, legger til et par sm\u00e5 knep og oppn\u00e5r fem eller ti ganger hastighets\u00f8kning, sier de: vel, det er ikke rettferdig, vi visste allerede at du var bedre. Utrolig. Hva var det jeg... kostnadsmodellen handler om hvilket kode du skriver og hvor raskt det i snitt kj\u00f8rer i et st\u00f8rre bilde.<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Hvordan kan man holde s\u00e5 mye informasjon i hodet? Oppn\u00e5s det gjennom mye erfaring, eller? Hvor f\u00e5r man slik erfaring fra?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Vel, min erfaring fikk jeg ikke p\u00e5 den enkleste m\u00e5ten. Jeg programmerte i Assembly p\u00e5 den tiden det var mulig \u00e5 forst\u00e5 hver eneste instruksjon. Det h\u00f8res dumt ut, men siden den gang har jeg hatt et sett med Z80-instruksjoner i hodet mitt for alltid. Jeg husker ikke navnet p\u00e5 folk bare et minutt etter samtalen, men jeg husker kode jeg skrev for 40 \u00e5r siden. Morsomt, det ser ut som syndromet til en \u00ab<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\">nerd<\/a><\/noindex>\u00bb.<\/p>\n<p><\/p>\n<h1 id=\"obuchenie-nizkourovnevym-optimizaciyam\">Learning low-level optimizations<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Finnes det en enklere m\u00e5te \u00e5 komme inn i dette p\u00e5?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: B\u00e5de ja og nei. Maskinvaren vi alle bruker, har ikke endret seg s\u00e5 mye i l\u00f8pet av denne tiden. Alle bruker x86, bortsett fra smarttelefoner med Arm. Hvis du ikke driver med hardcore embedded, har du det samme. Greit, videre. Instruksjoner har heller ikke endret seg p\u00e5 hundrevis av \u00e5r. Du m\u00e5 g\u00e5 og skrive noe i Assembly. Litt, men nok til \u00e5 begynne \u00e5 forst\u00e5. Du smiler, men jeg mener det helt alvorlig. Du m\u00e5 forst\u00e5 forholdet mellom spr\u00e5ket og maskinvaren. Etter dette m\u00e5 du skrive litt og lage en liten leke-kompilator for et lite leke-spr\u00e5k. \u201cLeke\u201d betyr at det m\u00e5 gj\u00f8res p\u00e5 en rimelig tid. Den kan v\u00e6re superenkel, men m\u00e5 generere instruksjoner. Aktet med instruksjonsgenerering vil gi deg en forst\u00e5else av kostnadsmodellen for broen mellom h\u00f8yniv\u00e5kode, som alle skriver i, og maskinkode, som kj\u00f8rer p\u00e5 maskinvaren. Dette forholdet vil brenne seg inn i hodet ditt mens du skriver kompilatoren. Selv den enkleste kompilatoren. Etter dette kan du begynne \u00e5 se p\u00e5 Java, og det at den har en semantisk avgrunn som er mye dypere, og lage broene over den, som er mye vanskeligere. I Java er det mye vanskeligere \u00e5 forst\u00e5 om broen v\u00e5r er god eller d\u00e5rlig, hva som vil f\u00e5 den til \u00e5 kollapse og hva som ikke vil. Men du trenger et startpunkt n\u00e5r du ser p\u00e5 koden og forst\u00e5r: \u201caha, denne getteren b\u00f8r inlinees hver gang\u201d. Og s\u00e5 viser det seg at noen ganger gj\u00f8r de det, bortsett fra n\u00e5r metoden blir for stor, og JIT begynner \u00e5 inline alt mulig. Ytelsen i disse tilfellene kan forutsies umiddelbart. Vanligvis fungerer gettere godt, men s\u00e5 ser du p\u00e5 store hot loops og innser at det er noen funksjonskall der som er uklare og hva de gj\u00f8r. Dette er problemet med den omfattende bruken av gettere, grunnen til at de ikke inlinees \u2013 det er uklart om dette er en getter. Hvis du har en superliten kodebase, kan du bare huske det og si: dette er en getter, og dette er en setter. I en stor kodebase lever hver funksjon sitt eget liv, som ingen egentlig kjenner til. Profileringsverkt\u00f8yet sier at vi har mistet 24% av tiden i en eller annen loop, og for \u00e5 forst\u00e5 hva denne loopen gj\u00f8r, m\u00e5 du se p\u00e5 hver funksjon inni. Det er umulig \u00e5 forst\u00e5 det uten \u00e5 studere funksjonen, og dette bremser forst\u00e5elsesprosessen betydelig. Derfor bruker jeg ikke gettere og settere; jeg har n\u00e5dd et nytt niv\u00e5!<br \/>\nHvor kan man finne en kostnadsmodell? Vel, man kan lese noe, selvf\u00f8lgelig... Men jeg tror den beste m\u00e5ten er \u00e5 handle. Lage en liten kompilator, og det vil v\u00e6re den beste m\u00e5ten \u00e5 forst\u00e5 kostnadsmodellen og f\u00e5 den inn i sitt eget hode. En liten kompilator som ville v\u00e6re nyttig for programmering av en mikrob\u00f8lgeovn \u2013 det er en oppgave for nybegynnere. Jeg mener, hvis du allerede har programmeringsevner, vil de v\u00e6re tilstrekkelige. Alle disse tingene som \u00e5 analysere en streng som vil v\u00e6re et eller annet algebraisk uttrykk, hente ut instruksjoner for matematiske operasjoner i riktig rekkef\u00f8lge, ta de riktige verdiene fra registrene \u2013 det gj\u00f8res lett. Og mens du gj\u00f8r dette, vil det bli trykket inn i hjernen. Jeg tror alle vet hva en kompilator gj\u00f8r. Og det vil gi forst\u00e5else for kostnadsmodellen.<\/p>\n<p><\/p>\n<h1 id=\"prakticheskie-primery-uluchsheniya-proizvoditelnosti\">Practical examples of performance improvements<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Hva annet b\u00f8r man v\u00e6re oppmerksom p\u00e5 n\u00e5r man jobber med ytelse?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Datastrukturer. Forresten, jeg har ikke hatt disse \u00f8ktene p\u00e5 lenge... <noindex>Rocket School<\/noindex>. Det var morsomt, men det krevde s\u00e5 mye innsats, og jeg har jo ogs\u00e5 et liv! Ok, s\u00e5 p\u00e5 en av de store og interessante \u00f8ktene, \"Hvor g\u00e5r ytelsen din\", ga jeg studentene et eksempel: To og en halv gigabyte fintech-data ble lest fra en CSV-fil, og s\u00e5 m\u00e5tte man telle antall solgte produkter. Vanlige tick-markedsdata. UDP-pakker, gjort om til tekstformat siden 70-tallet. Chicago Mercantile Exchange \u2013 diverse ting som olje, mais, soja og s\u00e5 videre. Man m\u00e5tte telle disse produktene, antall handler, gjennomsnittlig volum av transaksjoner og varer, osv. Det er ganske enkel handelsmatematikk: finne produktkoden (det er 1-2 tegn i en hash-tabell), f\u00e5 summen, legge den til en av handelssett, legge til volum, legge til kostnad, og et par andre ting. Veldig enkel matematikk. Den lekeaktige implementeringen var veldig lettfattelig: alt l\u00e5 i filen, jeg leste filen og gikk gjennom den, delte opp individuelle poster i Java-strenger, lette etter det n\u00f8dvendige og la sammen i henhold til den ovenfor beskrevne matematikken. Og dette fungerer med en viss hastighet. <\/p>\n<p><\/p>\n<p>Med denne tiln\u00e6rmingen er det \u00e5penbart hva som skjer, og parallelle beregninger vil ikke hjelpe her, ikke sant? Det viser seg at man kan oppn\u00e5 fem ganger bedre ytelse bare ved \u00e5 velge riktige datatyper. Dette overrasker til og med erfarne programmerere! I mitt spesifikke tilfelle var fokuset at man ikke b\u00f8r allokere minne i den varme sl\u00f8yfen. Vel, det er ikke hele sannheten, men generelt sett \u2013 unng\u00e5 \u00e5 allokere 'hver X', n\u00e5r X er stort nok. N\u00e5r X er to og en halv gigabyte, b\u00f8r man ikke allokere noe 'hver bokstav', eller 'hver linje', eller 'hver felt', ingenting av den typen. Det er akkurat dette som tar tid. Hvordan fungerer det egentlig? Tenk deg at jeg gj\u00f8r et kall <code>String.split()<\/code> eller <code>BufferedReader.readLine()<\/code>. <code>Readline<\/code> lager en streng fra en rekke bytes sendt over nettet, \u00e9n gang for hver linje, for hver av hundre millioner linjer. Jeg henter denne linjen, analyserer den og kaster den. Hvorfor kaster jeg den \u2013 vel, jeg har jo allerede behandlet den, s\u00e5 det er ferdig. S\u00e5 for hver byte som leses fra disse 2.7G, vil to tegn bli skrevet inn i strengen, det vil si allerede 5.4G, og de er ikke nyttige for meg videre, s\u00e5 de kastes. Hvis vi ser p\u00e5 minneb\u00e5ndbredden, laster vi 2.7G, som g\u00e5r gjennom minnet og minnebussen i prosessoren, og deretter blir det to ganger mer sendt til strengen i minnet, og alt dette blir prosessert hver gang en ny streng opprettes. Men jeg m\u00e5 jo lese den, hardwaren leser den, selv om alt senere blir prosessert. Og jeg m\u00e5 skrive den, fordi jeg har opprettet en streng og cacheminnet er overfylt \u2013 cachen kan ikke romme 2.7G. S\u00e5, for hver byte som leses, leser jeg to ekstra bytes og skriver to ekstra bytes, og til slutt har de et forhold p\u00e5 4:1 \u2013 slik bruker vi minneb\u00e5ndbredden un\u00f8dvendig. Og s\u00e5 viser det seg at hvis jeg gj\u00f8r <code>String.split()<\/code> \u2013 s\u00e5 gj\u00f8r jeg dette langt ifra for siste gang, det kan v\u00e6re ytterligere 6-7 felt inne i det. Derfor f\u00f8rer klassisk CSV-lesekode med p\u00e5f\u00f8lgende parsing av strenger til tap av minneb\u00e5ndbredde p\u00e5 rundt 14:1 sammenlignet med hva man faktisk ville ha. Hvis man slipper disse allokeringene, kan man oppn\u00e5 fem ganger raskere ytelse. <\/p>\n<p><\/p>\n<p>Og dette er ikke s\u00e5 veldig vanskelig. Hvis du ser p\u00e5 koden fra riktig vinkel, blir alt ganske enkelt, s\u00e5 snart du forst\u00e5r essensen av problemet. Det er ikke noe poeng i \u00e5 slutte \u00e5 allokere minne: problemet er bare at du allokerer noe, og det d\u00f8r med en gang, og underveis brenner det en viktig ressurs, som her er minneb\u00e5ndbredde. Og alt dette resulterer i redusert ytelse. P\u00e5 x86 m\u00e5 man vanligvis aktivt bruke prosessorens klokkesykluser, men her har du brent all minne mye tidligere. L\u00f8sningen er \u00e5 redusere antallet allokeringer.\u00a0<br \/>\nEn annen del av problemet er at hvis du kj\u00f8rer en profilerer n\u00e5r minneb\u00e5ndbredden er oppbrukt, akkurat i det \u00f8yeblikket det skjer, venter du vanligvis p\u00e5 at hurtigbufferen skal returnere, fordi den er full av s\u00f8ppelstoffene du nettopp har generert med alle disse linjene. Derfor blir hver load- eller store-operasjon treg, fordi de f\u00f8rer til cache-miss \u2013 hele hurtigbufferen har blitt treg, ventende p\u00e5 at s\u00f8ppel skal forlate. S\u00e5 profilereren vil bare vise en varm, tilfeldig st\u00f8y, spredt over hele syklusen \u2013 det vil ikke v\u00e6re noen separat hot-instruksjon eller sted i koden. Bare st\u00f8y. Og hvis du ser p\u00e5 GC-syklene, vil de alle v\u00e6re i Young Generation og superraske \u2013 mikrosekunder eller millisekunder maks. For alt dette minnet d\u00f8r umiddelbart. Du allokerer milliarder gigabyte, og den klipper dem, og klipper dem, og klipper dem igjen. Alt dette skjer veldig raskt. S\u00e5 det er billige GC-sykluser, varm st\u00f8y over hele syklusen, men vi \u00f8nsker \u00e5 oppn\u00e5 5x hastighets\u00f8kning. I dette \u00f8yeblikket m\u00e5 det klikke noe i hodet: \u00abHvorfor s\u00e5?!\u00bb. Overbelastning av minneb\u00e5ndbredde vises ikke i den klassiske feils\u00f8keren; du m\u00e5 kj\u00f8re en feils\u00f8ker for maskinvareressursene og se dette selv og direkte. Og indirekte kan man mistenke det fra disse tre symptomene. Det tredje symptomet er n\u00e5r du ser hva du allokerer, sp\u00f8r profilereren, og den svarer: \u00abDu har gjort en milliard linjer, men GC jobbet gratis\u00bb. S\u00e5 snart dette skjer, innser du at du har for mye objekter og har brent hele minneb\u00e5ndbredden. Det finnes en m\u00e5te \u00e5 finne ut av dette p\u00e5, men den er ikke \u00e5penbar.\u00a0<\/p>\n<p><\/p>\n<p>Problemet ligger i datastukturen: den bare strukturen bak alt som skjer er for stor, det er 2.7G p\u00e5 disken, s\u00e5 det er veldig u\u00f8nsket \u00e5 lage en kopi av denne tingen \u2013 man vil laste den direkte fra nettverksbytebufferet inn i registrene, for \u00e5 unng\u00e5 \u00e5 lese og skrive frem og tilbake fem ganger. Dessverre gir ikke Java deg et slikt bibliotek som standard i JDK. Men det er jo trivielt, ikke sant? I bunn og grunn er dette 5-10 linjer med kode som g\u00e5r til implementeringen av en egen bufferlaster for strenger, som etterligner oppf\u00f8rselen til strengklassen, mens det er en omslag rundt den underliggende bytebufferen. Resultatet er at du jobber nesten som om du bruker strenger, men egentlig flytter pekere til bufferen, og r\u00e5byte kopieres ingen steder, og dermed gjenbrukes de samme bufferne gang etter gang, mens operativsystemet gladelig tar seg av oppgaver det er laget for, som skjult dobbel buffering av disse bytebufferne, mens du selv ikke trenger \u00e5 behandle en uendelig str\u00f8m med un\u00f8dvendige data. Forresten, dere forst\u00e5r vel at ved arbeid med GC er det garantert at hver minnetildeling ikke vil bli sett av prosessoren etter den siste GC-syklusen? Derfor kan dette ikke v\u00e6re i cachen, og s\u00e5 skjer det en 100%-garantert misforst\u00e5else. Ved arbeid med pekeren, tar det p\u00e5 x86 1-2 klokkesykluser \u00e5 lese et register fra minnet, og s\u00e5 snart dette skjer, betaler du, betaler, betaler, for alle dataene er <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cache_inclusion_policy\">NINE cachingene<\/a><\/noindex> \u2013 og dette er kostnaden for minnetildeling. Den ekte kostnaden.<\/p>\n<p><\/p>\n<p>Med andre ord er datastrukturer det som er vanskeligst \u00e5 endre. Og s\u00e5 snart du innser at du har valgt feil datastruktur, som senere vil drepe ytelsen, krever det som regel en betydelig innsats \u00e5 gj\u00f8re det om, men hvis du ikke gj\u00f8r det, vil det bli verre. F\u00f8rst og fremst m\u00e5 du tenke p\u00e5 datastrukturer; det er viktig. De st\u00f8rste kostnadene her ligger i de<\/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>Andrei<\/strong>: Du sa at for \u00e5 forst\u00e5 kostnadsmodellen, m\u00e5 du skrive ditt eget lille spr\u00e5k\u2026<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ikke et spr\u00e5k, men en kompilator. Et spr\u00e5k og en kompilator er forskjellige ting. Den viktigste forskjellen er i hodet ditt.\u00a0<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: For \u00f8vrig, s\u00e5 vidt jeg vet, eksperimenterer du med \u00e5 lage egne spr\u00e5k. Hvorfor?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Fordi jeg kan! Jeg er delvis pensjonert, s\u00e5 dette er hobbyen min. Jeg har alltid jobbet med \u00e5 realisere andres spr\u00e5k. Jeg har ogs\u00e5 jobbet mye med kodingstil. Dessuten ser jeg problemer i andre spr\u00e5k. Jeg ser at det finnes bedre m\u00e5ter \u00e5 gj\u00f8re vanlige ting p\u00e5. Jeg ville brukt dem. Jeg er lei av \u00e5 se problemer med meg selv, i Java, i Python, i hvilket som helst annet spr\u00e5k. Jeg skriver n\u00e5 p\u00e5 React Native, JavaScript og Elm som en hobby som ikke handler om pensjon, men om aktivt arbeid. Og jeg skriver ogs\u00e5 i Python, og jeg vil mest sannsynlig fortsette \u00e5 jobbe med maskinl\u00e6ring for Java-backender. Det er mange popul\u00e6re spr\u00e5k, og alle har interessante egenskaper. Hvert spr\u00e5k har sine styrker og man kan pr\u00f8ve \u00e5 samle alle disse funksjonene i ett. S\u00e5, jeg studerer interessante ting for meg, spr\u00e5klig oppf\u00f8rsel, og pr\u00f8ver \u00e5 finne fornuftig semantikk. Og s\u00e5 langt g\u00e5r det bra! For \u00f8yeblikket sliter jeg med minnesemantikk, fordi jeg \u00f8nsker \u00e5 ha det slik som i C og Java, og f\u00e5 en sterk minnemodell og minnesemantikk for laster og lagringer. Samtidig \u00f8nsker jeg automatisk typeinferens som i Haskell. Her pr\u00f8ver jeg \u00e5 kombinere Haskell-lignende typeinferens med minne som fungerer som i C og Java. Dette har jeg jobbet med de siste 2-3 m\u00e5nedene, for eksempel.<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Hvis du lager et spr\u00e5k som tar de beste aspektene fra andre spr\u00e5k, har du tenkt p\u00e5 at noen kunne gj\u00f8re det motsatte: ta ideene dine og bruke dem selv?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Slik oppst\u00e5r nye spr\u00e5k! Hvorfor er Java likt C? Fordi C hadde en god syntaks som alle forstod, og Java ble inspirert av denne syntaksen, la til typesikkerhet, grensekontroller for tabeller, GC, og de forbedret noen ting i C. De la til sine egne. Men de ble ganske sterkt inspirert, ikke sant? Alle st\u00e5r p\u00e5 skuldrene til gigantene som kom f\u00f8r deg \u2013 slik skjer fremskritt.<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Som jeg forst\u00e5r det, vil spr\u00e5ket ditt v\u00e6re sikkert n\u00e5r det gjelder minnebruk. Har du tenkt p\u00e5 \u00e5 implementere noe lignende l\u00e5nekontrolleren fra Rust? Har du sett p\u00e5 den, hva synes du om den?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Vel, eg skrivur \u00e1 C dygd langa t\u00ed\u00f0, vi\u00f0 allar \u00feessar malloc og free, og st\u00fdri handvirkt l\u00edfslengd. Viti\u00f0 \u00fei\u00f0, 90-95% af handvirkri stj\u00f3rn \u00e1 l\u00edfslengd hefur s\u00f6mu uppbyggingu. Og \u00fea\u00f0 er mj\u00f6g, mj\u00f6g s\u00e1rt a\u00f0 vinna me\u00f0 \u00feetta handvirkt. Mig langar a\u00f0 compilerinn seg\u00f0i bara hva\u00f0 er a\u00f0 gerast og hva\u00f0 \u00fe\u00fa hefur n\u00e1\u00f0 me\u00f0 \u00fe\u00ednum a\u00f0ger\u00f0um. Fyrir sumar a\u00f0ger\u00f0ir gerir l\u00e1naathugunarinn \u00feetta beint \u00far kassanum. Og hann \u00e1 l\u00edka a\u00f0 sj\u00e1lfkrafa skila uppl\u00fdsingum, skilja allt og jafnvel ekki leggja \u00e1 mig byr\u00f0i a\u00f0 koma \u00feeirri skilningi \u00e1 framf\u00e6ri. Hann \u00e1 a\u00f0 framkv\u00e6ma a\u00f0 minnsta kosti sta\u00f0bundna fl\u00f3\u00f0i greiningu, og a\u00f0eins ef \u00fea\u00f0 tekst ekki, \u00fe\u00e1 \u00fearf a\u00f0 b\u00e6ta vi\u00f0 tegundarsk\u00fdringum sem munu l\u00fdsa l\u00edfslengd \u2013 og sl\u00edk uppbygging er mun fl\u00f3knari en l\u00e1naathugunarinn e\u00f0a \u00ed raun hva\u00f0a tilvistandi minni athugun. Vali\u00f0 milli \u201eallt \u00ed lagi\u201c og \u201e\u00e9g skil ekki neitt\u201c \u2014 nei, \u00fea\u00f0 \u00e6tti a\u00f0 vera eitthva\u00f0 betra.\u00a0<br \/>\nS\u00e5, som en person som har skrevet mye kode i C, mener jeg at st\u00f8tte for automatisk livstidsadministrasjon er det viktigste. Jeg er ogs\u00e5 lei av hvor mye Java bruker minne, og den st\u00f8rste klagen er GC. N\u00e5r du allokerer minne i Java, f\u00e5r du ikke tilbake minnet som var lokalt i den siste GC-syklusen. I spr\u00e5k med mer presis minneh\u00e5ndtering skjer ikke dette. Hvis du kaller malloc, f\u00e5r du umiddelbart minne som vanligvis nettopp har v\u00e6rt brukt. Vanligvis gj\u00f8r du midlertidige ting med minnet og returnerer det umiddelbart. Og det blir umiddelbart tilbakef\u00f8rt til malloc-poolen, og den neste malloc-syklusen henter det igjen. Derfor reduseres faktisk minnebruk til settet av levende objekter p\u00e5 et bestemt tidspunkt, pluss lekkasjer. Og hvis du ikke lekker p\u00e5 en skandal\u00f8s m\u00e5te, vil mesteparten av minnet bli liggende i hurtigbufferne og prosessoren, og det fungerer raskt. Men det krever mye manuell minneh\u00e5ndtering ved hjelp av malloc og free, kalt i riktig rekkef\u00f8lge, p\u00e5 riktig sted. Rust kan h\u00e5ndtere dette riktig og i mange tilfeller gi enda bedre ytelse, siden minneforbruket reduseres til de n\u00e5v\u00e6rende beregningene \u2013 i motsetning til \u00e5 vente p\u00e5 den neste GC-syklusen som frigj\u00f8r minne. Som et resultat har vi f\u00e5tt en veldig interessant m\u00e5te \u00e5 forbedre ytelsen p\u00e5. Og ganske kraftig \u2013 jeg har jobbet med slike ting for databehandling for fintech, og dette kunne gi en forbedring p\u00e5 omtrent fem ganger. Dette er en betydelig forbedring, spesielt i en verden hvor prosessorene ikke blir raskere, og vi fortsatt venter p\u00e5 forbedringer.<\/p>\n<p><\/p>\n<h1 id=\"karera-performans-inzhenera\">Career of a performance engineer<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Jeg vil gjerne sp\u00f8rre litt mer om karrieren generelt. Du ble kjent gjennom arbeidet p\u00e5 JIT i HotSpot, og deretter gikk du til Azul \u2013 som ogs\u00e5 er et JVM-selskap. Men du jobbet mer med maskinvare enn programvare. S\u00e5 plutselig gikk du over til Big Data og Maskinl\u00e6ring, og deretter til svindeldeteksjon. Hvordan skjedde dette? Det er veldig forskjellige omr\u00e5der innen utvikling.<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Jeg har holdt p\u00e5 med programmering i ganske lang tid og har hatt erfaring med mange forskjellige prosjekter. Og n\u00e5r folk sier: \u00ab\u00c5h, du er han som laget JIT for Java!\u00bb, er det alltid morsomt. F\u00f8r dette jobbet jeg med en klone av PostScript \u2013 det spr\u00e5ket som Apple en gang brukte for sine laserprintere. Og f\u00f8r det implementerte jeg Forth-spr\u00e5ket. Jeg tror det felles temaet for meg er utvikling av verkt\u00f8y. Hele livet har jeg laget verkt\u00f8y som andre mennesker bruker til \u00e5 skrive sine kule programmer. Men jeg har ogs\u00e5 jobbet med utvikling av operativsystemer, drivere, kjernedebuggeverkt\u00f8y, spr\u00e5k for OS-utvikling som begynte trivielt, men etter hvert ble mer og mer kompliserte. Hovedmessig handler det fortsatt om utvikling av verkt\u00f8y. En stor del av livet mitt gikk mellom Azul og Sun, og det handlet om Java. Men da jeg begynte med Big Data og Maskinl\u00e6ring, tok jeg p\u00e5 meg min fine hatt og sa: \u00ab\u00c5h, n\u00e5 har vi et ikke-trivielt problem, og det skjer virkelig mange interessante ting, med folk som gj\u00f8r noe\u00bb. Dette er en flott vei for utvikling som er verdt \u00e5 g\u00e5. <\/p>\n<p><\/p>\n<p>Ja, eg elskar distribuerte databehandling. Min f\u00f8rste jobb var som student med C, p\u00e5 et reklameprosjekt. Det var distribuerte databehandling p\u00e5 Zilog Z80-brikker som samlet data for analog optisk tegngjenkjenning, utf\u00f8rt av en faktisk analog analyser. Det var et kult og helt unormalt tema. Men det var problemer, en del av informasjonen ble ikke gjenkjent riktig, s\u00e5 det m\u00e5tte hentes et bilde og vises til en person som allerede hadde lest det med \u00f8ynene og informerte om hva som ble sagt, og derfor var det jobber med data, og disse jobbene hadde sitt eget spr\u00e5k. Det var en backend som h\u00e5ndterte alt dette \u2013 fungerende parallelle Z80 med kj\u00f8rende vt100-terminaler \u2013 \u00e9n per person, og det var en modell for parallell programmering p\u00e5 Z80. En felles minnedel som alle Z80 delte innen en konfigurasjonstype \u00abstjerne\u00bb; b\u00e5de backplane og halve RAM ble delt i nettverket, med den andre halvdelen privat eller brukt til noe annet. En betydelig kompleks parallell distribuert system med delt... halv-delt minne. N\u00e5r var dette... Jeg husker knapt, rundt midten av 80-tallet. Ganske lenge siden.\u00a0<br \/>\nJa, la oss si at 30 \u00e5r er ganske lenge. Oppgaver knyttet til distribuerte databehandling har eksistert en god stund, folk har i lang tid kjempet med <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>-klyster. Slike klyster ser ut som\u2026 For eksempel: det er Ethernet, og din raske x86 er koblet til dette Ethernet, og n\u00e5 \u00f8nsker du \u00e5 f\u00e5 fake shared memory, fordi ingen kunne da jobbe med koding av distribuerte beregninger, det var for komplisert, og derfor fantes det fake shared memory med sidetverrbeskyttelse p\u00e5 x86, og hvis du skrev til denne siden, s\u00e5 fortalte vi de andre prosessorene at hvis de fikk tilgang til den samme shared memory, m\u00e5tte den lastes inn fra deg, og p\u00e5 denne m\u00e5ten oppsto noe som lignet protokollen for cachekoherens og programvaren for dette. En interessant konsept. Det virkelige problemet var naturligvis noe annet. Alt dette fungerte, men du fikk raskt ytelsesproblemer, siden ingen forsto ytelsesmodellen p\u00e5 et tilstrekkelig godt niv\u00e5 \u2013 hvilke minnem\u00f8nstre som var der, hvordan man kunne forhindre at nodene pinget hverandre uendelig, og s\u00e5 videre. <\/p>\n<p><\/p>\n<p>I H2O har eg kome opp med dette: utviklarane sj\u00f8lve er ansvarlege for \u00e5 avgjere kvar parallelisme finst og kvar ho ikkje gjer det. Eg har utvikla ein kodingsmodell som gjer det lett og enkelt \u00e5 skrive h\u00f8gtytande kode. Men \u00e5 skrive kode som g\u00e5r sakte er vanskeleg, og den vil sj\u00e5 d\u00e5rleg ut. Ein m\u00e5 verkeleg anstrenge seg for \u00e5 skrive sakte kode; ein m\u00e5 bruke utradisjonelle metoder. Saktekodar er synlege ved f\u00f8rste augekast. Som eit resultat blir det som oftast skriven kode som g\u00e5r raskt, men ein m\u00e5 takle hva ein skal gjere med delt minne. Alt dette knytar seg til store array og oppf\u00f8rselen der liknar p\u00e5 ikkje-volatilar store array i parallell Java. Det vil seie, tenk deg at to tr\u00e5dar skriv til ein parallell array, den eine vinn, og den andre taper, og du veit ikkje kven som er kven. Om dei ikkje er volatile, kan rekkjef\u00f8lgja vere kva som helst \u2013 og dette fungerer faktisk veldig bra. Folk bryr seg verkeleg om rekkjef\u00f8lgja av operasjonar, dei plasserer volatile riktig og ventar p\u00e5 ytelsesproblem knytt til minnet p\u00e5 dei rette stadene. Ellers ville dei berre skrive kode i form av l\u00f8kker fr\u00e5 1 til N, der N er trillionar, i hopp om at alle vanskelege tilfelle automatisk ville bli parallelle \u2013 og det fungerer ikkje. Men i H2O er det verken Java eller Scala, ein kan sj\u00e5 p\u00e5 det som \"Java minus minus\", om ein \u00f8nskjer. Dette er ein veldig forst\u00e5eleg programmeringsstil og liknar p\u00e5 \u00e5 skrive enkel kode i C eller Java med l\u00f8kker og array. Men samtidig kan ein handtere minne p\u00e5 terabyte. Eg bruker framleis H2O. Fr\u00e5 tid til annan nyttar eg det i ulike prosjekt \u2013 og det er framleis det raskaste verkt\u00f8yet, mange gonger raskare enn konkurrentane. Om du arbeider med Big Data med kolonne-data, er det veldig vanskeleg \u00e5 overvinne H2O.<\/p>\n<p><\/p>\n<h1 id=\"tehnicheskie-chellenzhi\">Technical challenges<\/h1>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Kva har vore den st\u00f8rste utfordringa i karrieren din?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Diskuterer vi den tekniske eller ikkje-tekniske delen av sp\u00f8rsm\u00e5let? Eg vil seie at dei st\u00f8rste utfordringane ikkje er tekniske.\u00a0<br \/>\nN\u00e5r det gjelder tekniske utfordringer, overvant jeg dem. Jeg vet ikke engang hva som var den st\u00f8rste, men det var flere ganske interessante, som tok mye tid og mental kamp. Da jeg begynte i Sun, var jeg sikker p\u00e5 at jeg skulle lage en rask kompilator, men mange seniorer sa at jeg aldri kom til \u00e5 klare det. Men jeg gikk videre med dette, skrev kompilatoren helt opp til registerallokatoren, og den var ganske rask. Den var like rask som den moderne C1, men p\u00e5 den tiden var allokatoren mye tregere, og n\u00e5r jeg ser tilbake, var det et problem med store datastrukturer. Jeg trengte den for \u00e5 lage en grafisk registerallokator, og jeg forstod ikke dilemmaet mellom kodeuttrykk og hastighet som eksisterte p\u00e5 den tiden, og som var veldig viktig. Det viste seg at datastrukturen vanligvis oversteg st\u00f8rrelsen p\u00e5 cache-minnet p\u00e5 x86-er fra den tiden, og derfor, hvis jeg f\u00f8rst antok at registerallokatoren ville bruke 5-10 prosent av tiden i JIT-prosessen, endte det opp med \u00e5 v\u00e6re 50 prosent. <\/p>\n<p><\/p>\n<p>Tiden gikk, kompilatoren ble klarere og mer effektiv, den sluttet \u00e5 generere grusom kode i flere tilfeller, og ytelsen begynte oftere \u00e5 likne det som C-kompilatoren produserer. Med mindre du selvf\u00f8lgelig skriver noe s\u00f8ppel som selv C ikke kan optimalisere. Hvis du skriver kode som i C, oppn\u00e5r du ogs\u00e5 ytelse som i C i flere tilfeller. Og jo lenger vi kom, jo oftere genererte koden resultater som asymptotisk samsvarte med C-niv\u00e5, registerallokatoren begynte \u00e5 likne et fullf\u00f8rt prosjekt... uansett om koden din kj\u00f8rte raskt eller sakte. Jeg fortsatte \u00e5 jobbe med allokatoren for \u00e5 gi bedre tildelinger. Den ble saktere og saktere, men ga stadig bedre ytelse i situasjoner der ingen andre klarte det. Jeg kunne grave meg inn i registerallokatoren, bruke en m\u00e5ned p\u00e5 arbeid der, og plutselig begynte hele koden \u00e5 kj\u00f8re 5% raskere. Dette skjedde gang p\u00e5 gang, og registerallokatoren ble noe som et kunstverk - alle elsket eller hatet det, og folk fra akademia stilte sp\u00f8rsm\u00e5l om \"hvorfor alt gj\u00f8res p\u00e5 denne m\u00e5ten\", hvorfor ikke <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation#Linear_Scan\">line\u00e6r skanning<\/a><\/noindex>, og hva er forskjellen. Svaret er det samme: en allokator basert p\u00e5 graffarging pluss veldig n\u00f8ye arbeid med bufferkode er likt et v\u00e5pen for seier, den beste kombinasjonen som ingen kan overvinne. Og dette er ganske subtilt. Alt annet som kompilatoren gj\u00f8r, er ganske velkjente ting, selv om de ogs\u00e5 er l\u00f8ftet til kunstniv\u00e5. Jeg har alltid gjort ting som skulle forvandle kompilatoren til et kunstverk. Men ingenting av dette var noe ekstraordin\u00e6rt \u2013 bortsett fra registerallokatoren. Poenget er at man m\u00e5 v\u00e6re forsiktig <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation\">\u00e5 kutte<\/a><\/noindex> under belastning, og hvis dette skjer (jeg kan forklare n\u00e6rmere hvis det er interessant), betyr det at man kan inline mer aggressivt, uten risiko for \u00e5 overskride knekkpunktet i ytelsesgrafen. P\u00e5 den tiden var det mange fullskala kompilatorer, pyntet med finesser og klikkelyder, som hadde registerallokatorer, men ingen kunne gj\u00f8re det slik igjen. <\/p>\n<p><\/p>\n<p>Problemet er at dersom du legger til metoder som skal inline, og stadig \u00f8ker inline-omr\u00e5det, s\u00e5 vil settet av brukte verdier raskt overstige antallet registre, og man m\u00e5 spile. Det kritiske niv\u00e5et inntreffer ofte n\u00e5r allocatoren gir opp, og en god kandidat for spilling st\u00e5r i veien for en annen, slik at man ender opp med \u00e5 spile noen helt ville ting. Verdien av inlining ligger i det at man mister en del overhead, overhead p\u00e5 anrop og lagring, man kan se verdiene innenfor og kan optimalisere dem videre. Kostnaden ved inlining er at det dannes et stort antall aktive verdier, og hvis registerallocatorene mine spiler flere enn n\u00f8dvendig, taper jeg med \u00e9n gang. Derfor har de fleste allocatorer et problem: n\u00e5r inlining g\u00e5r over en viss grense, begynner alt \u00e5 spile, og ytelsen kan g\u00e5 nedover. De som implementerer kompilatoren, legger inn noen heuristikker: for eksempel for \u00e5 stoppe inlining n\u00e5r en viss st\u00f8rrelse er n\u00e5dd, ettersom allokeringene vil \u00f8delegge alt. Dette skaper et brudd i ytelsesgrafen \u2013 man inlineer, inlineer, ytelsen vokser sakte \u2013 og s\u00e5, bang! \u2013 faller det bratt nedover fordi man har inlineet for mye. Slik har det v\u00e6rt frem til Java dukket opp. Java krever mye mer inlining, s\u00e5 jeg m\u00e5tte lage min allocator mer aggressiv for at den skulle stabilisere seg og ikke falle. Og hvis du har inlineet for mye \u2013 begynner det \u00e5 spile, men det er alltid et punkt der man sier \u00abingen mer spilling\u00bb. Dette er en interessant observasjon og det kom til meg ganske uventet, ikke \u00e5penbart, men det har gitt gode resultater. Jeg tok for meg aggressiv inlining, og det f\u00f8rte meg til steder hvor ytelsen til Java og C g\u00e5r h\u00e5nd i h\u00e5nd. De er faktisk n\u00e6r hvertandre \u2013 jeg kan skrive kode i Java som er betydelig raskere enn kode i C og s\u00e5 videre, men i det store og hele, er de omtrent sammenlignbare. Det synes \u00e5 v\u00e6re en del av \u00e6ren for dette \u2013 registerallocatorene som lar meg inline s\u00e5 dumt som mulig. Jeg bare inlineer alt jeg kan se. Sp\u00f8rsm\u00e5let her er om allocatoren fungerer bra, og om resultatet er fornuftig fungerende kode. Dette var en stor utfordring: \u00e5 forst\u00e5 alt dette og f\u00e5 det til \u00e5 fungere.<\/p>\n<p><\/p>\n<h1 id=\"nemnogo-pro-allokaciyu-registrov-i-mnogoyadernost\">A little about register allocation and multithreading<\/h1>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Problemer som registerallokering synes \u00e5 v\u00e6re et evigvarende tema. Det er interessant om det har v\u00e6rt en id\u00e9 som s\u00e5 lovende ut, men som deretter mislyktes i praksis?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Selvf\u00f8lgelig! Registerallokering er et omr\u00e5de der du pr\u00f8ver \u00e5 finne noen heuristikker for \u00e5 l\u00f8se et NP-komplett problem. Og du vil aldri kunne oppn\u00e5 en perfekt l\u00f8sning, ikke sant? Det er simpelthen umulig. Se p\u00e5 Ahead of Time-kompilering \u2013 det fungerer ogs\u00e5 d\u00e5rlig. Her handler det om noen gjennomsnittlige tilfeller. Om typisk ytelse, s\u00e5 du kan g\u00e5 og m\u00e5le noe du anser som god typisk ytelse \u2013 tross alt, jobber du med \u00e5 forbedre den! Registerallokering er et tema som utelukkende er viet ytelse. S\u00e5 snart du har den f\u00f8rste prototypen, fungerer den og gj\u00f8r det den skal, begynner arbeidet med ytelsen. Du m\u00e5 l\u00e6re deg \u00e5 m\u00e5le godt. Hvorfor er dette viktig? Hvis det finnes klare data, kan du se p\u00e5 forskjellige deler og se: ah, dette hjalp her, men der br\u00f8t alt sammen! Det dukker opp noen gode ideer, du legger til en ny heuristikk, og plutselig begynner alt \u00e5 fungere litt bedre i gjennomsnitt. Eller ikke. Jeg har hatt mange tilfeller der vi kjempet for fem prosent ytelse som skilte v\u00e5r utvikling fra den forrige allokatoren. Og hver gang ser det slik ut: et sted vant vi, et annet sted tapte vi. Hvis du har gode ytelsesanalysverkt\u00f8y, kan du finne tapende ideer og forst\u00e5 hvorfor de taper. Kanskje er det bedre \u00e5 la alt v\u00e6re som det er, eller kanskje ta en mer seri\u00f8s tiln\u00e6rming til finjustering, eller g\u00e5 og fikse noe annet. Dette er en hel rekke ting! Jeg lagde denne kule hakken, men trenger ogs\u00e5 denne, denne, og denne \u2013 og den totale kombinasjonen gir noen forbedringer. Og enkeltst\u00e5ende kan mislykkes. Slik er naturen ved arbeid med ytelse av NP-komplette problemer.<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Det f\u00f8les som om ting som farging i allokatorer er en oppgave som allerede er l\u00f8st. Vel, for dere er det l\u00f8st, if\u00f8lge det dere forteller, s\u00e5 er det egentlig verdt \u00e5\u2026<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Den er ikke l\u00f8st som s\u00e5dan. Det er op til dig at g\u00f8re den \"l\u00f8st\". Der findes tunge opgaver, og de skal l\u00f8ses. N\u00e5r det er gjort, er det tid til at arbejde p\u00e5 ydelsen. Dette arbejde skal tages alvorligt - lave benchmarks, samle metrikker, forklare situationer, n\u00e5r du g\u00e5r tilbage til en tidligere version, og dit gamle hack pludselig begyndte at fungere igen (eller omvendt, stoppede). Og du m\u00e5 ikke give op, f\u00f8r du opn\u00e5r noget. Som jeg allerede har sagt, er der mange fede ideer, der ikke virkede, men i omr\u00e5det for registerallokering er ideerne stort set uendelige. Du kan for eksempel l\u00e6se videnskabelige publikationer. Selvom dette omr\u00e5de nu bev\u00e6ger sig langsommere og er blevet mere klart end i sin ungdom, arbejder der stadig en uendelig m\u00e6ngde mennesker her, og deres ideer er alle v\u00e6rd at pr\u00f8ve, de venter alle p\u00e5 deres tid. Og du kan ikke sige, hvor gode de er, hvis du ikke pr\u00f8ver dem. Hvor godt de integreres med alt andet i din allokator, for allokatoren g\u00f8r mange ting, og nogle ideer i din specifikke allokator vil ikke fungere, mens de fungerer perfekt i en anden allokator. Den prim\u00e6re m\u00e5de at vinde for allokatoren p\u00e5 er at tr\u00e6kke langsomme dele uden for den prim\u00e6re sti og tvinge split ved gr\u00e6nserne af langsomme stier. S\u00e5 hvis du \u00f8nsker at starte GC, tage den langsomme vej, deoptimere, kaste undtagelsen, alt det der - du ved, at disse ting er relativt sj\u00e6ldne. Og de er virkelig sj\u00e6ldne, jeg har tjekket. Du laver ekstra arbejde, og takket v\u00e6re dette forsvinder mange begr\u00e6nsninger p\u00e5 disse langsomme stier, men det er ikke s\u00e5 vigtigt, fordi de er langsomme, og de er sj\u00e6ldent benyttet. For eksempel, en null-pointer - det sker aldrig, ikke? Du skal have flere veje til forskellige ting, men de skal ikke blande sig p\u00e5 hovedvejen.\u00a0<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Hvad mener du om multikernede processorer, n\u00e5r vi taler om tusinder af kerner? Er det nyttigt?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Succesen med GPU'er viser, at det er ret nyttigt!<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: De er ret specialiserede. Hvad med almene processor?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Vel, dette var forretningsmodellen til Azul. Svaret kom i en tid da folk virkelig satte pris p\u00e5 forutsigbar ytelse. Det var da vanskelig \u00e5 skrive parallellkode. H2O-modellen skalerer godt, men den er ikke en generell modell. Bare litt mer generell enn ved bruk av GPU. Snakker vi om kompleksiteten ved \u00e5 utvikle noe slikt, eller kompleksiteten ved \u00e5 bruke det? For eksempel, en interessant l\u00e6rdom fra Azul, ganske uventet: sm\u00e5 hurtigbuffer er helt greit.\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>: Hva med de ikke-tekniske utfordringene?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Den st\u00f8rste utfordringen var \u00e5 ikke v\u00e6re\u2026 vennlig og god mot folk. Og som et resultat, havnet jeg stadig i ekstremt konfliktfulle situasjoner. Situasjoner der jeg visste at alt gikk galt, men ikke visste hvordan jeg skulle g\u00e5 videre med \u00e5 l\u00f8se disse problemene, og klarte ikke \u00e5 h\u00e5ndtere dem. Mange langvarige problemer, som har vart i ti\u00e5r, oppstod nettopp p\u00e5 denne m\u00e5ten. At det finnes C1- og C2-kompilatorer i Java, er et direkte resultat av dette. Det faktum at det ikke har v\u00e6rt flere niv\u00e5er av kompilering i Java i ti \u00e5r, er ogs\u00e5 et direkte resultat. Det er \u00e5penbart at vi trengte et slikt system, men det er ikke \u00e5penbart hvorfor det ikke fantes. Jeg hadde problemer med en ingeni\u00f8r\u2026 eller en gruppe ingeni\u00f8rer. For lenge siden, da jeg begynte \u00e5 jobbe i Sun, var jeg\u2026 Vel, ikke bare da, jeg har alltid en mening om alt. Og jeg trodde p\u00e5 sannheten i \u00e5 bare ta denne sannheten min og si det rett ut. Spesielt siden jeg ofte faktisk hadde rett. Og hvis du ikke liker en slik tiln\u00e6rming\u2026 spesielt hvis du \u00e5penbart tar feil og gj\u00f8r noe dumt\u2026 Vel, f\u00e5 mennesker kunne tolerere en slik kommunikasjonsform. Selv om noen kunne, for eksempel meg. Jeg har bygd hele livet mitt p\u00e5 meritokratiske prinsipper. Hvis du viser meg noe som er feil, snur jeg meg umiddelbart og sier: du har sagt noe dumt. Samtidig, selvf\u00f8lgelig, beklager jeg, og alt det der, anerkjenner fortjenester, hvis de i det hele tatt eksisterer, og gj\u00f8r andre riktige handlinger. P\u00e5 den andre siden har jeg faktisk rett en sjokkerende stor prosentandel av tiden. Og det fungerer ikke s\u00e5 bra i forhold til folk. Jeg pr\u00f8ver ikke \u00e5 v\u00e6re hyggelig, men setter sp\u00f8rsm\u00e5l ved saken direkte. \"Dette vil aldri fungere, fordi \u00e9n, to og tre.\" Og de sier: \"\u00c5h!\". Det var ogs\u00e5 andre konsekvenser, som det kanskje er best \u00e5 hoppe over: for eksempel som f\u00f8rte til skilsmisse fra kona og ti \u00e5r med depresjon etter det.<\/p>\n<p><\/p>\n<p>En utfordring er en kamp med folk, med oppfatningen av hva du kan eller ikke kan gj\u00f8re, hva som er viktig og hva som ikke er. Det har v\u00e6rt mange utfordringer rundt kodestil. Jeg skriver fortsatt mye kode, og p\u00e5 den tiden m\u00e5tte jeg til og med senke tempoet, fordi jeg gjorde for mange oppgaver samtidig og gjorde det d\u00e5rlig, i stedet for \u00e5 fokusere p\u00e5 \u00e9n oppgave. Ser jeg tilbake, skrev jeg halvparten av koden til Java JIT-teamet, C2-teamet. Den neste raskeste koderen skrev halvparten s\u00e5 raskt, den neste igjen enda langsommere, og det var en eksponentiell nedgang. Den syvende personen i rekken var veldig, veldig treg \u2013 s\u00e5nn er det alltid! Jeg har v\u00e6rt involvert i mye kode. Jeg har sett hvem som skriver hva, uten unntak, jeg har stirret p\u00e5 koden deres, vurdert hver og en av dem, og jeg skrev fortsatt mer enn noen av dem. Denne tiln\u00e6rmingen fungerer ikke s\u00e5 bra med folk. Noen liker ikke det. Og n\u00e5r de ikke klarer \u00e5 h\u00e5ndtere det, begynner det \u00e5 komme diverse klager. For eksempel, en gang ble jeg bedt om \u00e5 slutte \u00e5 skrive kode, fordi jeg skrev for mye kode, og det truet teamet, og det hele h\u00f8rtes ut som en sp\u00f8k for meg: hvis hele det gjenv\u00e6rende teamet forsvinner, og jeg fortsetter \u00e5 skrive kode, vil du bare miste halvparten av teamet. P\u00e5 den annen side, hvis jeg fortsetter \u00e5 skrive kode og du mister halvparten av teamet \u2013 det h\u00f8res ut som veldig d\u00e5rlig ledelse. Jeg har aldri tenkt s\u00e5 mye over det, aldri snakket om det, men det var fortsatt et sted i bakhodet mitt. I bakhodet surret tanken: \u00abEr dere egentlig seri\u00f8se?\u00bb. S\u00e5 den st\u00f8rste utfordringen var meg og mine relasjoner med folk. N\u00e5 forst\u00e5r jeg meg selv mye bedre. Jeg har v\u00e6rt teamleder for programmerere i lang tid, og n\u00e5 sier jeg direkte til folk: vet du, jeg er den jeg er, og dere m\u00e5 bare finne ut av det \u2013 er det greit at jeg st\u00e5r her? Og n\u00e5r de begynte \u00e5 h\u00e5ndtere det, begynte alt \u00e5 fungere. Jeg er jo verken d\u00e5rlig eller god, jeg har ingen d\u00e5rlige intensjoner eller egoistiske ambisjoner, det er bare min natur, og man m\u00e5 p\u00e5 en eller annen m\u00e5te leve med det.<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Nylig har alle begynt \u00e5 snakke om selvbevissthet for introverte, og generelt om myke ferdigheter. Hva kan man si om dette?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ja, det var en forst\u00e5else og en l\u00e6rdom jeg fikk fra skilsmissen med min ekskone. Hva jeg l\u00e6rte fra skilsmissen \u2013 var forst\u00e5elsen av meg selv. S\u00e5 begynte jeg \u00e5 forst\u00e5 andre mennesker. Forst\u00e5 hvordan denne interaksjonen fungerer. Dette f\u00f8rte til oppdagelser, en etter en. Jeg ble klar over hvem jeg er og hva jeg st\u00e5r for. Hva jeg gj\u00f8r: enten jeg er opptatt med oppgaven, unng\u00e5r konflikt, eller noe annet \u2013 og et slikt niv\u00e5 av selvbevissthet hjelper virkelig med \u00e5 holde seg i sjakk. Etter dette blir alt mye enklere. En ting jeg oppdaget ikke bare om meg selv, men ogs\u00e5 om andre programmerere \u2013 er umuligheten av \u00e5 verbalisere tanker n\u00e5r man er i en tilstand av emosjonelt stress. For eksempel, du sitter og koder, befinner deg i en flow-tilstand, og s\u00e5 kommer noen og begynner \u00e5 skrike i panikk om at noe er \u00f8delagt, og n\u00e5 vil de ta grove tiltak. Og du kan ikke si et ord fordi du er i en tilstand av emosjonelt stress. Den tilegnede kunnskapen gj\u00f8r at du kan forberede deg p\u00e5 dette \u00f8yeblikket, oppleve det og g\u00e5 over til en tilbaketrekning, etter hvilket du kan begynne \u00e5 handle. S\u00e5 ja, n\u00e5r du begynner \u00e5 forst\u00e5 hvordan alt dette fungerer \u2013 er det en stor livsendrende hendelse.\u00a0<br \/>\nJeg klarte selv ikke \u00e5 finne de riktige ordene, men jeg husket rekkef\u00f8lgen av handlingene. Poenget er at denne reaksjonen er like fysisk som den er verbal, og du trenger rom. Et slikt rom, i zen-sinn. Dette er akkurat det som m\u00e5 forklares, og s\u00e5 m\u00e5 man straks trekke seg tilbake \u2013 fysisk trekke seg tilbake. N\u00e5r jeg er stille med ordene, kan jeg bearbeide situasjonen i f\u00f8lelser. Etter hvert som adrenalinet n\u00e5r hjernen og setter deg i 'sl\u00e5 eller l\u00f8p' modus, kan du ikke si noe, nei \u2013 n\u00e5 er du idiot, m\u00e5l for frustrasjon, ute av stand til \u00e5 gi et verdig svar eller til \u00e5 i det minste stoppe angrepet, og angriperen kan fritt angripe igjen og igjen. F\u00f8rst m\u00e5 du bli deg selv igjen, gjenvinne kontrollen, g\u00e5 ut av 'sl\u00e5 eller l\u00f8p' modus. <\/p>\n<p><\/p>\n<p>Og for dette er det n\u00f8dvendig med et verbalt rom. Bare et fritt rom. Hvis man i det hele tatt skal si noe, kan man nettopp si dette, og s\u00e5 g\u00e5 og faktisk finne seg et \u00abrom\u00bb: g\u00e5 en tur i parken, l\u00e5se seg inne i dusjen \u2013 det spiller ingen rolle. Det viktigste er \u00e5 midlertidig koble ut fra situasjonen. S\u00e5 snart du klarer \u00e5 koble ut selv bare for et par sekunder, kommer kontrollen tilbake, og du begynner \u00e5 tenke klart. \u00abBra, jeg er jo ikke en idiot, jeg gj\u00f8r ikke dumme ting, jeg er en ganske nyttig person\u00bb. S\u00e5 snart du har klart \u00e5 overbevise deg selv, er det p\u00e5 tide \u00e5 g\u00e5 videre til neste steg: forst\u00e5 hva som har skjedd. Du har blitt angrepet, angrepet kom fra et uventet hold, det var en urettferdig og feig bakhold. Dette er d\u00e5rlig. Neste steg er \u00e5 forst\u00e5 hvorfor angriperen gjorde dette. Virkelig, hvorfor? Kanskje fordi han selv er rasende? Hvorfor er han rasende? For eksempel fordi han selv har rotet det til og ikke kan ta ansvar? P\u00e5 denne m\u00e5ten m\u00e5 man forsiktig h\u00e5ndtere hele situasjonen. Men for dette trenger man rom for man\u00f8vrering, et verbalt rom. Det aller f\u00f8rste steget er \u00e5 bryte den verbale kontakten. \u00c5 trekke seg unna diskusjonen med ord. Avbryt det, g\u00e5 bort s\u00e5 raskt som mulig. Hvis det er en telefonsamtale \u2013 legg bare p\u00e5; det er en ferdighet jeg fikk fra kommunikasjon med min ekskone. Hvis samtalen ikke f\u00f8rer med seg noe bra, si bare \u00abha det\u00bb og legg p\u00e5. P\u00e5 den andre siden av telefonen: \u00abbla-bla-bla\u00bb, og du svarer: \u00abaha, ha det!\u00bb og s\u00e5 legger du p\u00e5. Du bare avbryter samtalen. Fem minutter senere, n\u00e5r evnen til \u00e5 tenke klart kommer tilbake til deg, har du kj\u00f8lt deg ned litt, og det blir mulig \u00e5 tenke over hva som faktisk har skjedd og hva som vil skje videre. Og begynne \u00e5 formulere et gjennomtenkt svar, i stedet for bare \u00e5 reagere p\u00e5 f\u00f8lelsene. For meg var det et gjennombrudd i selvbevisstheten nettopp det at jeg ikke kan snakke i tilfelle emosjonelt stress. \u00c5 komme ut av denne tilstanden, tenke over og planlegge hvordan man skal svare og h\u00e5ndtere problemene \u2013 dette er de riktige stegene n\u00e5r man ikke kan snakke. Den enkleste m\u00e5ten er \u00e5 r\u00f8mme fra situasjonen der emosjonelt stress oppst\u00e5r og rett og slett slutte \u00e5 delta i den stressen. Etter dette gjenf\u00e5r du evnen til \u00e5 tenke, n\u00e5r du kan tenke, f\u00e5r du muligheten til \u00e5 snakke, og s\u00e5 videre.<\/p>\n<p><\/p>\n<p>Forresten, i retten pr\u00f8ver motpartens advokat \u00e5 gj\u00f8re dette med deg \u2013 n\u00e5 er det klart hvorfor. Fordi han har muligheten til \u00e5 undertrykke deg til et punkt der du ikke engang kan si navnet ditt, for eksempel. I ordets mest bokstavelige betydning, kan du ikke snakke. Hvis dette skjer med deg, og hvis du vet at du vil befinne deg i et sted der ordslagsm\u00e5l blusser, et sted som retten, s\u00e5 kan du komme med din egen advokat. Advokaten din vil forsvare deg og stoppe den verbale angrepet, og gj\u00f8re det p\u00e5 lovlig vis, og du vil f\u00e5 tilbake ditt tapte zen-rom. For eksempel, jeg m\u00e5tte ringe familien et par ganger, dommeren var ganske vennlig om det, men motpartens advokat ropte og ropte p\u00e5 meg, jeg kunne ikke engang f\u00e5 inn et ord. I slike tilfeller fungerer det best for meg \u00e5 bruke en megler. Megleren stanser alt dette presset som str\u00f8mmer mot deg kontinuerlig, du finner det n\u00f8dvendige zen-rommet, og sammen med det kommer evnen til \u00e5 snakke tilbake. Dette er et helt kunnskapsfelt der man m\u00e5 l\u00e6re mye, oppdage mye inni seg, og alt dette forvandles til h\u00f8y-niv\u00e5 strategiske beslutninger, forskjellige for forskjellige mennesker. Noen har ikke de nevnte problemene, vanligvis har ikke folk som jobber profesjonelt med salg. Alle disse menneskene som tjener til livets opphold med ord \u2013 kjente sangere, poeter, religi\u00f8se figurer og politikere, de har alltid noe \u00e5 si. De har ikke slike problemer, men jeg har dem.<\/p>\n<p><\/p>\n<p><strong>Andrei<\/strong>: Det var\u2026 uventet. Flott, vi har allerede snakket ganske mye og det er p\u00e5 tide \u00e5 avslutte dette intervjuet. Vi ses definitivt p\u00e5 konferansen, og vi kan fortsette denne dialogen. Vi sees p\u00e5 Hydra!<\/p>\n<p><\/p>\n<blockquote><p>Du kan fortsette samtalen med Cliff p\u00e5 Hydra 2019 konferansen, som vil finne sted 11.-12. juli 2019 i Sankt Petersburg. Han vil komme med et innlegg <noindex><a rel=\"nofollow\" href=\"https:\/\/hydraconf.com\/2019\/talks\/2jix5mst7iduyp9linqhfj\/?utm_source=habr&amp;utm_medium=45871\">\u00abThe Azul Hardware Transactional Memory experience\u00bb<\/a><\/noindex>. Billetter kan kj\u00f8pes <noindex><a rel=\"nofollow\" href=\"https:\/\/hydraconf.ru\/?utm_source=habr&amp;utm_medium=458718\">p\u00e5 den offisielle nettsiden<\/a><\/noindex>.<\/p><\/blockquote>\n<p>Kilde: <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\/no\/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=\"nn_NO\" \/>\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\/no\/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\udd47Stort intervju med Cliff Click \u2014 faren til JIT-kompilering i Java | ProHoster","description":"Cliff Click \u2014.","canonical_url":"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nn_NO","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\/no\/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\/no\/wp-json\/wp\/v2\/posts\/35851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/comments?post=35851"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts\/35851\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/media?parent=35851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/categories?post=35851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/tags?post=35851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}