{"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\/da\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","title":{"rendered":"Stort interview med Cliff Click \u2014 faderen til JIT-kompileringen i Java","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Stort interview med Cliff Click \u2014 faderen til JIT-kompileringen i Java\" src=\"\/wp-content\/uploads\/2019\/07\/9ea9740ef74c0ae14d334482af115222.png\" style=\"display:block;margin: 0 auto;\" \/><strong>Cliff Click<\/strong> \u2014 CTO for 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 years old (Pascal for TRS Z-80)! He is most 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 became one of the factors in establishing Java 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. In general, Cliff has worked 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>Transition to low-level optimizations<\/li>\n<li>How to perform a large refactoring<\/li>\n<li>Cost model<\/li>\n<li>Learning low-level optimizations<\/li>\n<li>Practical examples of performance improvement<\/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 multi-core systems<\/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. In his career, he has worked on a variety of projects: testing distributed NewSQL databases at Yandex, a cloud detection system at Kaspersky Lab, a multiplayer game at Mail.ru, and a currency pricing service at Deutsche Bank. He's 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 more than 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\">Transition 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>: That's right!<\/p>\n<p><\/p>\n<p><strong>Andrey<\/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 like working at the CPU level?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Her er det ganske enkelt. Den hurtigste kode er den, der aldrig k\u00f8res. Derfor skal man altid starte med et h\u00f8jt niveau og arbejde med algoritmerne. En bedre tidskompleksitet vil sl\u00e5 en d\u00e5rligere, medmindre der er nogle ret store konstanter involveret. Lav-niveau ting kommer sidst. Normalt, hvis du har optimeret hele den \u00f8vrige stak godt nok, og der stadig er noget interessant tilbage \u2013 s\u00e5 er det lav-niveau. Men hvordan starter man med det h\u00f8je niveau? Hvordan ved man, at man har gjort tilstr\u00e6kkeligt arbejde p\u00e5 h\u00f8jt niveau? N\u00e5... ikke rigtig. Der er ingen f\u00e6rdige opskrifter. Du skal forst\u00e5 problemet, beslutte, hvad du vil g\u00f8re (for ikke at lave un\u00f8dvendige skridt senere), og s\u00e5 kan du tage fat p\u00e5 profilleren, som kan sige noget nyttigt. P\u00e5 et tidspunkt forst\u00e5r du selv, at du har fjernet un\u00f8dvendige elementer, og det er tid til at fokusere p\u00e5 finjustering af lav niveau. Det er bestemt en s\u00e6rlig form for kunst. Mange mennesker laver un\u00f8dvendige ting, men arbejder s\u00e5 hurtigt, at de ikke har tid til at bekymre sig om ydeevnen. Men det er, indtil sp\u00f8rgsm\u00e5let bliver kritisk. Normalt er 99% af tiden ingen interesseret i, hvad jeg laver, indtil der opst\u00e5r noget vigtigt p\u00e5 den kritiske vej, som nogen bekymrer sig om. Og s\u00e5 begynder alle at stille sp\u00f8rgsm\u00e5l som: 'Hvorfor fungerede det ikke perfekt fra starten af?' Generelt er der altid noget at forbedre i ydeevnen. Men 99% af tiden har du ikke noget at gribe fat i! Du pr\u00f8ver bare at f\u00e5 noget til at fungere, og i l\u00f8bet af det forst\u00e5r du, hvad der er vigtigt. Du kan aldrig vide p\u00e5 forh\u00e5nd, at denne specifikke del skal g\u00f8res perfekt, s\u00e5 essensen er, at du skal v\u00e6re perfekt i alt. Og det er umuligt, og du g\u00f8r det ikke. Der er altid mange ting, der skal repareres \u2013 og det er helt normalt.<\/p>\n<p><\/p>\n<h1 id=\"kak-delat-bolshoy-refaktoring\">How to perform a large refactoring<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Hvordan arbejder du med ydeevnen? Det er jo et gennemg\u00e5ende problem. Har du for eksempel v\u00e6ret n\u00f8dt til at arbejde med problemer, der opst\u00e5r p\u00e5 grund af overlapning af en stor m\u00e6ngde eksisterende funktionalitet?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Jeg pr\u00f8ver at undg\u00e5 dette. Hvis jeg ved, at ydeevnen vil blive et problem, t\u00e6nker jeg over det, f\u00f8r jeg begynder at kode, is\u00e6r n\u00e5r det kommer til datastrukturer. Men ofte opdager man det f\u00f8rst meget senere. Og s\u00e5 m\u00e5 man tage drastiske skridt og g\u00f8re det, jeg kalder \u00abgenskriv og hersk\u00bb: man skal tage fat i en stor del. En del af koden skal stadig skrives om p\u00e5 grund af ydeevneproblemer eller andet. Uanset \u00e5rsagen til at skrive koden om, er det n\u00e6sten altid bedre at skrive en st\u00f8rre del om end en mindre del. I det \u00f8jeblik begynder alle at ryste af frygt: \u00ab\u00e5h gud, vi kan ikke r\u00f8re s\u00e5 meget kode!\u00bb Men faktisk fungerer en s\u00e5dan tilgang n\u00e6sten altid meget bedre. Man skal straks tage fat p\u00e5 det store problem, skitsere en stor cirkel omkring det og sige: alt inden for cirklen, det vil jeg skrive om. Gr\u00e6nsen er meget mindre end det indhold, der ligger inden for den, som skal udskiftes. Og hvis en s\u00e5dan afgr\u00e6nsning g\u00f8r det muligt at g\u00f8re arbejdet inden i perfekt \u2013 s\u00e5 har du frie h\u00e6nder, g\u00f8r hvad du vil. S\u00e5 snart du har forst\u00e5et problemet, bliver geniskrivningsprocessen meget nemmere, s\u00e5 tag en stor bid!<br \/>\nSamtidig, n\u00e5r du genwriter i store bidder og forst\u00e5r, at ydeevnen vil blive et problem, kan du begynde at bekymre dig om det med det samme. Dette bliver ofte til enkle ting som \u00abkopier ikke data, h\u00e5ndter data s\u00e5 enkelt som muligt, g\u00f8r dem mindre\u00bb. I store genskrivninger er der standardmetoder til at forbedre ydeevnen. Og de handler n\u00e6sten altid om data.<\/p>\n<p><\/p>\n<h1 id=\"model-stoimosti\">Cost model<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: I en af podcasterne talte du om omkostningsmodeller i forbindelse med ydeevne. Kan du forklare, hvad du mente med det?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Selvf\u00f8lgelig. Jeg blev f\u00f8dt i en tid, hvor processorens ydeevne var ekstremt vigtig. Og denne \u00e6ra vender tilbage \u2013 sk\u00e6bnen er ikke uden ironi. Jeg begyndte at leve i tiderne med 8-bit maskiner, min f\u00f8rste computer arbejdede med 256 bytes. Ja, bytes. Alt var meget lille. Man skulle t\u00e6lle instruktioner, og s\u00e5 snart vi begyndte at bev\u00e6ge os op ad stakken af programmeringssprog, tog sprogene mere og mere ansvar. Der var assembler, s\u00e5 Basic, s\u00e5 C, og C tog sig af mange detaljer, som registreringsfordeling og instruktionsevaluering. Men der var alt sammen ret klart, og hvis jeg lavede en peger til en instansvariabel, ville jeg f\u00e5 load, og denne instruktion havde en kendt omkostning. Hardwaren leverede et kendt antal maskincykler, s\u00e5 hastigheden af forskellige operationer kunne let beregnes ved at l\u00e6gge alle instruktioner sammen, som du planlagde at k\u00f8re. Hver sammenligning\/test\/forgrening\/opkald\/load\/store kunne samles og man kunne sige: det er tiden for udf\u00f8relsen. N\u00e5r man forbedrer ydeevnen, vil man helt sikkert bem\u00e6rke, hvilke tal der svarer til de sm\u00e5, varme cykler.\u00a0<br \/>\nMen s\u00e5 snart du skifter til Java, Python og lignende ting, bev\u00e6ger du dig meget hurtigt v\u00e6k fra det lave hardware-niveau. Hvad er omkostningen ved at kalde en getter i Java? Hvis JIT i HotSpot har gjort det rigtigt, <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.openjdk.java.net\/display\/HotSpot\/Inlining\">inlinet<\/a><\/noindex>, s\u00e5 bliver det et load, men hvis det ikke gjorde det \u2013 bliver det et funktionsopkald. Da opkaldet ligger p\u00e5 det varme cyklus, vil det oph\u00e6ve alle andre optimeringer i denne cyklus. Derfor vil den reelle omkostning v\u00e6re meget h\u00f8jere. Og man mister straks evnen til at se p\u00e5 et kodestykke og forst\u00e5, hvad det koster at udf\u00f8re det i forhold til processorens klokkefrekvens, anvendt hukommelse og cache. Alt dette bliver interessant, n\u00e5r man virkelig graver ned i ydeevnen.<br \/>\nVi befinder os nu i en situation, hvor processorernes hastigheder n\u00e6sten ikke er steget i et helt \u00e5rti. De gamle tider er tilbage! Du kan ikke l\u00e6ngere regne med god enkelttr\u00e5det ydeevne. Men hvis du pludselig skal besk\u00e6ftige dig med parallel computing \u2013 er det sindssygt sv\u00e6rt, alle ser p\u00e5 dig som om du er James Bond. Ti gange acceleration forekommer s\u00e6dvanligvis der, hvor nogen har overset noget. Parallellitet kr\u00e6ver meget arbejde. For at opn\u00e5 den ti-foldige acceleration skal du forst\u00e5 omkostningsmodellen. Hvad koster hvad, og hvor meget? Og for det skal du forst\u00e5, hvordan sproget passer ind i det underliggende hardware.<br \/>\nMartin Thompson fandt et fremragende ord til sin blog <noindex><a rel=\"nofollow\" href=\"https:\/\/mechanical-sympathy.blogspot.com\/\">Mechanical Sympathy<\/a><\/noindex>! Det er vigtigt at forst\u00e5, hvad hardwaren fors\u00f8ger at g\u00f8re, hvordan den vil g\u00f8re det, og hvorfor den overhovedet g\u00f8r det, den g\u00f8r. Ved at bruge denne forst\u00e5else er det forholdsvis enkelt at begynde at t\u00e6lle instruktioner og finde ud af, hvor tiden bruges. Hvis du derimod ikke har den rette baggrund, leder du bare efter en sort kat i et m\u00f8rkt rum. Jeg ser konstant folk, der optimerer ydeevnen, uden den mindste id\u00e9 om, hvad pokker de egentlig laver. De k\u00e6mper meget og kommer ikke rigtig noget sted. Og n\u00e5r jeg tager den samme kode, tilf\u00f8jer et par sm\u00e5 tweaks og opn\u00e5r fem- eller ti-foldig acceleration, siger de: N\u00e5, det er ikke fair, vi vidste jo, at du var bedre. Utroligt. Hvad var det nu, jeg sagde\u2026 omkostningsmodellen handler om, hvad for kode du skriver, og hvor hurtigt den i gennemsnit k\u00f8rer i den overordnede sammenh\u00e6ng.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Og hvordan holder man s\u00e5 s\u00e5 meget i hovedet? Opn\u00e5s det gennem en masse erfaring, eller? Hvor f\u00e5r man s\u00e5dan erfaring fra?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: N\u00e5, jeg har ikke f\u00e5et min erfaring den nemmeste vej. Jeg programmerede i assembler tilbage, da man kunne finde ud af hver enkelt instruktion. Det lyder dumt, men siden da har jeg for evigt haft et s\u00e6t Z80-instruktioner i hukommelsen. Jeg kan ikke huske folks navne et minut efter samtalen, men jeg husker koden skrevet for 40 \u00e5r siden. Det er sjovt, det ligner et '<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\">idiot-savante<\/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>: Er der nogen lettere m\u00e5de at komme ind i det p\u00e5?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ja og nej. Hardwaren, vi alle bruger, har ikke \u00e6ndret sig s\u00e5 meget i denne tid. Alle bruger x86, undtagen smartphones med Arm. Hvis du ikke arbejder med hardcore embedded udvikling, s\u00e5 har du det samme som alle andre. Godt, videre. Instruktionerne har heller ikke \u00e6ndret sig i \u00e5rtier. Du skal tage hen og skrive noget i Assembly. Lidt, men nok til at begynde at forst\u00e5. I ser m\u00e5ske grinende ud, men jeg taler helt alvorligt. Det er n\u00f8dvendigt at forst\u00e5 forholdet mellem sprog og hardware. Derefter skal du begynde at skrive lidt og lave en lille leget\u00f8jscompiler til et lille leget\u00f8jssprog. \u201cLeget\u00f8j\u201d betyder, at du skal lave det inden for rimelig tid. Det kan v\u00e6re super enkelt, men det skal generere instruktioner. Handlingen med at generere instruktioner vil g\u00f8re det muligt at forst\u00e5 omkostningsmodellen for broen mellem den h\u00f8jniveau kode, som alle skriver, og maskinkoden, der k\u00f8rer p\u00e5 hardwaren. Dette forhold vil br\u00e6nde sig ind i hjernen, n\u00e5r man skriver compiler. Selv den mest simple compiler. Herefter kan man begynde at kigge p\u00e5 Java og se, at dens semantiske kl\u00f8ft er meget dybere, og at det er langt mere kompliceret at bygge broer over den. I Java er det meget sv\u00e6rere at forst\u00e5, om vores bro er god eller d\u00e5rlig, hvad der vil f\u00e5 den til at kollapsere, og hvad der ikke vil. Men du har brug for et udgangspunkt, n\u00e5r du kigger p\u00e5 koden og forst\u00e5r:<br \/>\nHvor kan man finde en prismodel? Man kan naturligvis l\u00e6se noget... Men jeg tror, den bedste m\u00e5de er at handle. At lave en lille compiler vil v\u00e6re den bedste m\u00e5de at forst\u00e5 prismodellen p\u00e5 og f\u00e5 den ind i sin egen bevidsthed. En lille compiler, der kunne bruges til at programmere en mikrob\u00f8lgeovn \u2013 det er en opgave for en nybegynder. Jeg mener, hvis du allerede har programmeringsf\u00e6rdigheder, burde det v\u00e6re tilstr\u00e6kkeligt. Alle disse ting som at parse en streng, der vil v\u00e6re et eller andet algebraisk udtryk, tr\u00e6kke instruktioner til matematiske operationer ud i den rigtige r\u00e6kkef\u00f8lge, tage de rette v\u00e6rdier fra registrene \u2013 alt dette g\u00f8res p\u00e5 et \u00f8jeblik. Og mens du g\u00f8r det, vil det blive indprentet i din hjerne. Jeg tror, alle ved, hvad en compiler g\u00f8r. Og det vil give forst\u00e5else for prismodellen.<\/p>\n<p><\/p>\n<h1 id=\"prakticheskie-primery-uluchsheniya-proizvoditelnosti\">Practical examples of performance improvement<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Hvad andet b\u00f8r man v\u00e6re opm\u00e6rksom p\u00e5, n\u00e5r man arbejder med ydeevne?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Datastrukturer. For resten, jeg har ikke haft disse lektioner i lang tid... <noindex>Rocket School<\/noindex>. Det var sjovt, men kr\u00e6vede s\u00e5 meget arbejde, og jeg har jo ogs\u00e5 et liv! N\u00e5. I et af de store og interessante kurser, \"Hvor kommer din performance hen?\", gav jeg studerende et eksempel: To og en halv gigabyte fintech-data blev l\u00e6st fra en CSV-fil og derefter skulle antallet af solgte produkter beregnes. Almindelige tick-markedsdata. UDP-pakker, der blev omdannet til tekstformat siden 70'erne. Chicago Mercantile Exchange \u2013 forskellige ting som olie, majs, soja og s\u00e5 videre. Man skulle t\u00e6lle disse produkter, antallet af handler, gennemsnitligt transaktionsvolumen osv. Det er forholdsvis simpel handelsmatematik: finde produktkoden (det er 1-2 tegn i en hash-tabel), f\u00e5 summen, tilf\u00f8je den til et af handelsbatches, tilf\u00f8je volumen, tilf\u00f8je omkostninger, og et par andre ting. Meget simpel matematik. Den leget\u00f8jsimplementering var meget ligetil: alt ligger i filen, jeg l\u00e6ser filen og bev\u00e6ger mig gennem den, opdeler de enkelte poster til Java-strenge, finder de n\u00f8dvendige ting i dem og l\u00e6gger dem sammen if\u00f8lge ovenst\u00e5ende matematik. Og det fungerer med en vis hastighed. <\/p>\n<p><\/p>\n<p>Med en s\u00e5dan tilgang er det \u00e5benlyst, hvad der foreg\u00e5r, og parallelle beregninger vil ikke hj\u00e6lpe her, korrekt? Det viser sig, at man kun ved at v\u00e6lge de rigtige datatyper kan opn\u00e5 en femfoldig stigning i ydeevnen. Og det overrasker selv erfarne programm\u00f8rer! I mit specifikke tilf\u00e6lde handlede fokus om, at man ikke b\u00f8r lave hukommelsesallokeringer i en varm cyklus. N\u00e5, det er ikke hele sandheden, men generelt set skal man ikke allokere \"hver gang i X\", n\u00e5r X er stort nok. N\u00e5r X er to og en halv gigabyte, b\u00f8r man ikke allokere noget \"hver gang for en bogstav\", eller \"hver gang for en linje\", eller \"hver gang for et felt\", ingenting af den slags. Det er netop her, tiden g\u00e5r tabt. Hvordan fungerer det overhovedet? Forestil dig, at jeg laver et kald <code>String.split()<\/code> eller <code>BufferedReader.readLine()<\/code>. <code>Readline<\/code> der laver en streng fra en r\u00e6kke bytes, der er sendt over netv\u00e6rket, \u00e9n gang for hver linje, for hver af de hundrede millioner linjer. Jeg tager denne linje, analyserer den og smider den v\u00e6k. Hvorfor smider jeg den v\u00e6k \u2013 n\u00e5, jeg har jo allerede behandlet den, det er det. S\u00e5 for hver byte, der er l\u00e6st fra disse 2.7G, vil der blive skrevet to tegn i strengen, alts\u00e5 allerede 5.4G, og de er ikke l\u00e6ngere nyttige for mig, s\u00e5 jeg smider dem v\u00e6k. Hvis man ser p\u00e5 hukommelsens b\u00e5ndbredde, s\u00e5 indl\u00e6ser vi 2.7G, som g\u00e5r gennem hukommelsen og hukommelsesbussen i processor, og derefter sendes der to gange mere til strengen, der ligger i hukommelsen, og alt dette bearbejdes, n\u00e5r hver ny streng oprettes. Men jeg skal l\u00e6se den, hardwaren l\u00e6ser den, selvom alt senere bliver bearbejdet. Og jeg skal skrive den, fordi jeg har oprettet en streng, og caches er fyldt \u2013 cache kan ikke rumme 2.7G. S\u00e5 for hver l\u00e6st byte l\u00e6ser jeg ogs\u00e5 to ekstra bytes og skriver to ekstra bytes, og til sidst har de et forhold p\u00e5 4:1 \u2013 vi spilder p\u00e5 den m\u00e5de hukommelsens b\u00e5ndbredde. Og det viser sig, at hvis jeg g\u00f8r <code>String.split()<\/code> \u2013 s\u00e5 g\u00f8r jeg det langt fra sidste gang, derinde kan der v\u00e6re yderligere 6-7 felter. Derfor f\u00f8rer den klassiske kode til l\u00e6sning af CSV med efterf\u00f8lgende parsing af strenge til tab af hukommelsesb\u00e5ndbredde p\u00e5 omkring 14:1 i forhold til, hvad man faktisk gerne vil have. Hvis man undg\u00e5r disse allokeringer, kan man opn\u00e5 en femfoldig acceleration. <\/p>\n<p><\/p>\n<p>Og det er ikke, fordi det er s\u00e6rligt sv\u00e6rt. Hvis du ser p\u00e5 koden fra den rette vinkel, s\u00e5 bliver alt dette ret simpelt, s\u00e5 snart du indser essensen af problemet. Du skal overhovedet ikke stoppe med at allokere hukommelse: problemet er kun, at du allokerer noget, og det d\u00f8r straks, hvilket forbruger en vigtig ressource, som i dette tilf\u00e6lde er hukommelsesb\u00e5ndbredde. Og alt dette resulterer i et fald i ydeevnen. P\u00e5 x86 skal man normalt aktivt bruge CPU-taktter, men her har du allerede forbrugt al hukommelse langt tidligere. L\u00f8sningen er at reducere antallet af allokeringer.\u00a0<br \/>\nEn anden del af problemet er, at hvis du k\u00f8rer en profiler, n\u00e5r hukommelsesb\u00e5ndbredden er opbrugt, pr\u00e6cis i det \u00f8jeblik, hvor det sker, forventer du ofte at f\u00e5 cache tilbage, fordi den er fyldt med skrald, som du lige har skabt, med alle disse r\u00e6kker. S\u00e5 hver load- eller store-operation bliver langsom, fordi de f\u00f8rer til cache-misser \u2013 hele cachen er blevet langsom, mens den venter p\u00e5, at skraldet forlader den. Derfor viser profiler kun varmt tilf\u00e6ldigt st\u00f8j, spredt langs hele cyklussen \u2013 der vil ikke v\u00e6re nogen separat varm instruktion eller et sted i koden. Kun st\u00f8j. Og hvis du kigger p\u00e5 GC-cyklusserne, vil alle v\u00e6re i Young Generation og superhurtige \u2013 mikrosekunder eller millisekunder maksimalt. Al denne hukommelse d\u00f8r \u00f8jeblikkeligt. Du allokerer milliarder af gigabyte, og den klipper dem af, og klipper dem af, og klipper dem af. Alt dette sker meget hurtigt. S\u00e5 der er billige GC-cyklusser, varm st\u00f8j langs hele cyklussen, men vi \u00f8nsker at opn\u00e5 en 5-dobbelt acceleration. P\u00e5 det tidspunkt skal noget g\u00e5 op for en: \u00abhvorfor?!\u00bb. Overbelastning af hukommelsesb\u00e5ndbredden vises ikke i den klassiske debugger; du skal k\u00f8re en debugger for hardware-performance-t\u00e6llere og se det selv direkte. Og ikke direkte kan du mist\u00e6nke det ud fra disse tre symptomer. Det tredje symptom er, n\u00e5r du ser, hvad du allokerer, sp\u00f8rger profiler, og den svarer: \u00abDu har lavet en milliard r\u00e6kker, men GC arbejdede gratis\u00bb. S\u00e5 snart dette sker, indser du, at du har skabt for mange objekter og har forbrugt hele hukommelsesb\u00e5ndbredden. Der er en m\u00e5de at finde ud af dette p\u00e5, men den er ikke indlysende.\u00a0<\/p>\n<p><\/p>\n<p>Problemet ligger i datakonstru ktionen: den r\u00e5 struktur, der ligger bag alt dette, er for stor; den fylder 2.7G p\u00e5 disken, s\u00e5 det er ikke \u00f8nskeligt at lave en kopi af denne ting \u2013 man vil gerne indl\u00e6se den direkte fra netv\u00e6rksbytebufferen til registre, s\u00e5 man ikke l\u00e6ser og skriver frem og tilbage fem gange. Desv\u00e6rre giver Java som standard ikke s\u00e5dan et bibliotek i JDK. Men det er jo trivielt, ikke? I bund og grund er det 5-10 linjer kode, der vil implementere en egen bufferloader til linjer, der efterligner opf\u00f8rselen af string-klassen, samtidig med at den fungerer som en wrapper omkring den underliggende bytebuffer. Resultatet bliver, at du n\u00e6sten arbejder som med strenge, men i virkeligheden bev\u00e6ger der sig blot pointere til bufferen, og r\u00e5 bytes kopieres ikke nogen steder, og p\u00e5 den m\u00e5de genbruges de samme buffere igen og igen, og operativsystemet er glad for at tage sig af de opgaver, det er beregnet til, s\u00e5som skjult dobbeltbuffering af disse bytebuffere, s\u00e5 du ikke l\u00e6ngere maler en endel\u00f8s str\u00f8m af un\u00f8dvendige data. Forresten, forst\u00e5r I, at der med GC garanteres, at hver allokering af hukommelse ikke vil v\u00e6re synlig for processoren efter den sidste GC-cyklus? Derfor kan alt dette slet ikke v\u00e6re i cachen, og s\u00e5 sker der 100% garanti for et cache-miss. Ved arbejde med en pointer, tager det p\u00e5 x86 1-2 clock cycles at l\u00e6se et register fra hukommelsen, og s\u00e5 snart det sker, betaler du, betaler du, betaler du, fordi al hukommelse er p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cache_inclusion_policy\">NINE caches<\/a><\/noindex> \u2013 og det er prisen for hukommelsesallokering. Den reelle pris.<\/p>\n<p><\/p>\n<p>Med andre ord er datastrukturer det, der er sv\u00e6rest at \u00e6ndre. Og s\u00e5 snart du indser, at du har valgt en forkert datastruktur, der i fremtiden vil dr\u00e6be pr\u00e6stationen, kr\u00e6ver det normalt betydelig arbejde at \u00e6ndre det, men hvis du ikke g\u00f8r det, vil situationen kun blive v\u00e6rre. F\u00f8rst og fremmest skal man t\u00e6nke p\u00e5 datastrukturer; det er vigtigt. Den prim\u00e6re omkostning ligger her p\u00e5 tunge datastrukturer, som folk begynder at bruge med tanken: \"Jeg kopierede datastruktur X til datastruktur Y, fordi Y ser bedre ud for mig.\" Men kopieringsoperationen (som virker billig) bruger faktisk b\u00e5ndbredde, og her ligger alt det mistede udf\u00f8relsestid. Hvis jeg har en gigantisk streng med JSON, og jeg vil omdanne den til et struktureret DOM-tr\u00e6 af POJO'er eller noget lignende, vil parsing af denne streng og opbygningen af POJO'er, og derefter et nyt opkald til POJO'erne senere, medf\u00f8re un\u00f8dvendige omkostninger \u2013 det er ikke billigt. Medmindre du planl\u00e6gger at behandle POJO'erne meget oftere end strengen. Som en hurtig l\u00f8sning kan du pr\u00f8ve at dekode strengen og tr\u00e6kkes n\u00f8dvendige informationer ud uden at omdanne til POJO'er. Hvis alt dette foreg\u00e5r p\u00e5 en vej, hvor maksimal ydeevne kr\u00e6ves, er der ingen POJO'er \u2013 du skal finde en m\u00e5de at arbejde direkte med strengen p\u00e5.<\/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>: Du sagde, at for at forst\u00e5 omkostningsmodellen, skal man skrive sit eget lille sprog ...<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Ikke et sprog, men en compiler. Sprog og compiler er to forskellige ting. Den vigtigste forskel er i dit hoved.\u00a0<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: For \u00f8vrigt, som jeg ved, eksperimenterer du med at skabe dine egne sprog. Hvorfor?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Fordi jeg kan! Jeg er halvt pensioneret, s\u00e5 det her er mit hobby. Jeg har hele mit liv implementeret andres sprog. Og s\u00e5 har jeg arbejdet meget med kodestil. Ogs\u00e5 fordi jeg ser problemer i andre sprog. Jeg kan se, at der er bedre m\u00e5der at g\u00f8re velkendte ting p\u00e5. Og jeg ville bruge dem. Jeg er bare tr\u00e6t af at se problemer i mig selv, i Java, i Python, i hvilket som helst andet sprog. Jeg skriver nu i React Native, JavaScript og Elm som en hobby, der ikke handler om pension, men om aktivt arbejde. Og jeg skriver ogs\u00e5 i Python, og sandsynligvis vil jeg forts\u00e6tte med at arbejde med maskinl\u00e6ring for Java-backends. Der er mange popul\u00e6re sprog, og hvert af dem har interessante egenskaber. Hvert sprog er godt til noget, og man kan pr\u00f8ve at samle alle disse funktioner. S\u00e5 jeg studerer de ting, der interesserer mig, adf\u00e6rd af sprog, og pr\u00f8ver at finde p\u00e5 fornuftig semantik. Og indtil videre klarer jeg mig godt! I \u00f8jeblikket k\u00e6mper jeg med semantik for hukommelsen, fordi jeg gerne vil have det, som i C og Java, og f\u00e5 en st\u00e6rk hukommelsesmodel og hukommelsessemantik for load og store. Samtidig vil jeg have automatisk typeaflednings som i Haskell. Jeg pr\u00f8ver at blande Haskell-lignende typeaflednings med hukommelse, der fungerer som i C og Java. Det har jeg arbejdet med de sidste 2-3 m\u00e5neder, for eksempel.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Hvis du bygger et sprog, der tager de bedste aspekter fra andre sprog, har du t\u00e6nkt over, at nogen m\u00e5ske vil g\u00f8re det omvendte: tage dine ideer og bruge dem i deres eget?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: S\u00e5dan opst\u00e5r der nye sprog! Hvorfor ligner Java C? Fordi C havde en god syntaks, som alle forstod, og Java blev inspireret af den syntaks, tilf\u00f8jede type-sikkerhed, arrays gr\u00e6nsekontrol, GC, og de forbedrede nogle ting fra C. De tilf\u00f8jede deres egne. Men de var ret meget inspireret, ikke? Alle st\u00e5r p\u00e5 skuldrene af k\u00e6mperne, der var f\u00f8r dig - s\u00e5dan g\u00f8r man fremskridt.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Som jeg forst\u00e5r det, vil dit sprog v\u00e6re sikkert i forhold til brug af hukommelse. Har du overvejet at implementere noget som borrow checker fra Rust? Har du kigget p\u00e5 det, hvad synes du?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Jeg har allerede skrevet i C i en evighed, med alt dette malloc og free, og jeg administrerer livscyklussen manuelt. Ved du, 90-95% af den manuelt styrede livscyklus har den samme struktur. Og det er meget, meget smertefuldt at h\u00e5ndtere dette manuelt. Jeg ville \u00f8nske, at compilerens output bare sagde, hvad der sker, og hvad jeg har opn\u00e5et med mine handlinger. For nogle ting g\u00f8r borrow checker dette ud af boksen. Og det skal ogs\u00e5 automatisk udlede information, forst\u00e5 alt og endda ikke overbelaste mig med at skulle formulere den forst\u00e5else. Det skal lave mindst en lokal escape-analyse, og kun hvis det ikke lykkes, s\u00e5 skal der tilf\u00f8jes typeannoteringer, der beskriver livscyklussen \u2013 og en s\u00e5dan ordning er langt mere kompleks end borrow checker eller overhovedet enhver eksisterende hukommelseschecker. Valget mellem 'alt er i orden' og 'jeg forstod ikke noget' \u2014 nej, der skal v\u00e6re noget bedre.\u00a0<br \/>\nSom en person, der har skrevet meget kode i C, mener jeg, at st\u00f8tte til automatisk livscyklusstyring er en af de vigtigste ting. Jeg er ogs\u00e5 tr\u00e6t af, hvor meget Java bruger hukommelse, og en af de st\u00f8rste klager er omkring GC. N\u00e5r du tildeler hukommelse i Java, f\u00e5r du ikke den hukommelse tilbage, der var lokal i den sidste GC-cyklus. I sprog med mere pr\u00e6cis hukommelseskontrol er det ikke s\u00e5dan. Hvis du kalder malloc, f\u00e5r du straks hukommelse, der netop er blevet brugt. Normalt laver du nogle midlertidige ting med hukommelsen og returnerer den straks. Og den g\u00e5r straks tilbage til malloc-poolen, og den n\u00e6ste malloc-cyklus tr\u00e6kker den ud igen. Derfor reduceres det faktiske hukommelsesforbrug til m\u00e6ngden af levende objekter p\u00e5 et givet tidspunkt plus l\u00e6kager. Og hvis du ikke l\u00e6kker p\u00e5 en helt skandal\u00f8s m\u00e5de, vil det meste af hukommelsen lande i cache og processoren, og det fungerer hurtigt. Men det kr\u00e6ver meget manuel hukommelsesh\u00e5ndtering ved hj\u00e6lp af malloc og free, der kaldes i den rigtige r\u00e6kkef\u00f8lge og p\u00e5 det rigtige sted. Rust kan selv h\u00e5ndtere dette korrekt og i mange tilf\u00e6lde endda give bedre ydeevne, da hukommelsesforbruget begr\u00e6nses til de aktuelle beregninger \u2013 i mods\u00e6tning til at vente p\u00e5 den n\u00e6ste GC-cyklus, der frigiver hukommelse. Resultatet er, at vi har f\u00e5et en meget interessant m\u00e5de at forbedre ydeevnen p\u00e5. Og ret kraftfuld \u2013 jeg har arbejdet med s\u00e5danne ting i databehandling for fintech, og det kunne give en acceleration p\u00e5 omkring fem gange. Det er en ret stor acceleration, is\u00e6r i en verden, hvor processorer ikke bliver hurtigere, men vi stadig 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>Andrey<\/strong>: Jeg vil ogs\u00e5 gerne sp\u00f8rge om din karriere generelt. Du blev ber\u00f8mt for dit arbejde med JIT i HotSpot og bev\u00e6gede dig derefter til Azul \u2013 og det er ogs\u00e5 et JVM-selskab. Men du har arbejdet mere med hardware end software. Og s\u00e5 pludselig skiftede du til Big Data og Machine Learning, og senere til svindelbek\u00e6mpelse. Hvordan gik det til? Det er meget forskellige udviklingsomr\u00e5der.<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Jeg har arbejdet med programmering i lang tid og har v\u00e6ret involveret i mange forskellige projekter. Og n\u00e5r folk siger: \u00ab\u00c5h, du er ham, der lavede JIT til Java!\u00bb, er det altid sjovt. F\u00f8r det arbejdede jeg med en klon af PostScript \u2013 det sprog, som Apple engang brugte til deres laserprintere. Og f\u00f8r det implementerede jeg Forth-sproget. Jeg tror, at min gennemg\u00e5ende interesse er udvikling af v\u00e6rkt\u00f8jer. Jeg har hele mit liv lavet v\u00e6rkt\u00f8jer, som hj\u00e6lper andre med at skrive deres fantastiske programmer. Men jeg har ogs\u00e5 arbejdet med udvikling af operativsystemer, drivere, kernel-niveau debuggere og sprog til operativsystemudvikling, der startede simpelt, men som blev mere og mere komplekse over tid. Men det prim\u00e6re fokus er stadig udvikling af v\u00e6rkt\u00f8jer. En stor del af mit liv er blevet tilbragt mellem Azul og Sun, og det handlede om Java. Men da jeg begyndte med Big Data og Machine Learning, tog jeg igen min festhat p\u00e5 og sagde: \u00ab\u00c5h, nu st\u00e5r vi over for et ikke-trivielt problem, og der sker virkelig en masse interessante ting og mennesker, der laver noget.\u00bb Det er en fantastisk vej for udvikling, som er v\u00e6rd at g\u00e5. <\/p>\n<p><\/p>\n<p>Ja, jeg elsker virkelig distribueret computing. Mit f\u00f8rste job var i studietiden med C, p\u00e5 et reklameprojekt. Det handlede om distribueret computing p\u00e5 Zilog Z80-chip, som indsamlede data til analog optisk tekstgenkendelse, der blev udf\u00f8rt af en \u00e6gte analog analyser. Det var et fedt og helt unormalt emne. Men der var problemer; en del blev ikke genkendt korrekt, s\u00e5 man skulle tage billedet frem og vise det til en person, der allerede havde l\u00e6st det med \u00f8jnene og kunne fort\u00e6lle, hvad det handlede om. Derfor var der job med data, og disse job havde deres eget sprog. Der var en backend, der behandlede det hele \u2013 fungerende Z80'er k\u00f8rte parallelt med vt100-terminaler \u2013 \u00e9n pr. person, og der var en model for parallel programmering p\u00e5 Z80. En slags f\u00e6lles hukommelse, som alle Z80 delte inden for en stjernelignende konfiguration; b\u00e6kplen blev delt, og halvdelen af RAM'en blev delt inden for netv\u00e6rket, og den anden halvdel var privat eller gik til noget andet. En meningsfuld kompleks parallel distribueret system med delt... halv-delt hukommelse. Hvorn\u00e5r var det her... Kan n\u00e6sten ikke huske det, et sted i midten af 80'erne. Ret lang tid siden.\u00a0<br \/>\nJa, lad os sige, at 30 \u00e5r er ret lang tid. Opgaver relateret til distribueret computing har eksisteret l\u00e6nge, og folk har k\u00e6mpet med det i lang tid. <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>-klystrer. S\u00e5danne klystrer ser ud som\u2026 For eksempel: der er Ethernet, og din hurtige x86 er tilsluttet dette Ethernet, og nu \u00f8nsker du at f\u00e5 fat i fake shared memory, fordi ingen kunne dengang arbejde med kodning af distribuerede beregninger, det var for sv\u00e6rt, og derfor var der fake shared memory med beskyttelse af hukommelsessider p\u00e5 x86. Hvis du skrev til denne side, fortalte vi de andre processorer, at hvis de fik adgang til den samme shared memory, skulle den hentes fra dig, og p\u00e5 den m\u00e5de opstod der noget som en protokol til st\u00f8tte for cache-koherens og software til dette. En interessant koncept. Det virkelige problem var selvf\u00f8lgelig et andet. Alt dette fungerede, men du fik hurtigt problemer med ydeevnen, for ingen forstod ydeevnemodellen p\u00e5 et tilstr\u00e6kkeligt godt niveau \u2013 hvilke adgangsm\u00f8nstre til hukommelsen der var, hvordan man fik noderne til ikke konstant at pinge hinanden, og s\u00e5 videre. <\/p>\n<p><\/p>\n<p>I H2O har jeg fundet ud af f\u00f8lgende: selv udviklerne er ansvarlige for at bestemme, hvor parallelismen gemmer sig, og hvor den ikke g\u00f8r. Jeg har skabt en kodningsmodel, der g\u00f8r det let og enkelt at skrive h\u00f8jtydende kode. Men at skrive langsomt fungerende kode er sv\u00e6rt, og det vil se d\u00e5rligt ud. Man skal virkelig g\u00f8re en indsats for at skrive langsom kode; det kr\u00e6ver ikke-standardmetoder. Bremsende kode er synlig ved f\u00f8rste \u00f8jekast. Som f\u00f8lge heraf skrives der normalt kode, der fungerer hurtigt, men man m\u00e5 finde ud af, hvad man skal g\u00f8re i tilf\u00e6lde af delt hukommelse. Alt dette er knyttet til store arrays, og opf\u00f8relsen der minder om ikke-flygtige store arrays i parallelt Java. T\u00e6nk p\u00e5 det p\u00e5 denne m\u00e5de: to tr\u00e5de skriver til et parallelt array, en af dem vinder, og den anden, selvf\u00f8lgelig, taber, og du ved ikke, hvem der er hvem. Hvis de ikke er flygtige, kan r\u00e6kkef\u00f8lgen v\u00e6re hvad som helst \u2013 og det fungerer faktisk rigtig godt. Folk bekymrer sig virkelig om r\u00e6kkef\u00f8lgen af operationer, de placerer volatile korrekt og forventer p\u00e5 de rigtige steder problemer med ydeevne relateret til hukommelse. Ellers ville de bare skrive kode som l\u00f8kker fra 1 til N, hvor N er nogle trillioner, i h\u00e5bet om at alle komplekse tilf\u00e6lde automatisk bliver parallelle \u2013 og det virker ikke der. Men i H2O er det hverken Java eller Scala, man kan betragte det som 'Java minus minus', hvis man vil. Det er en meget forst\u00e5elig programmeringsstil, og den ligner at skrive simpel kode i C eller Java med l\u00f8kker og arrays. Men samtidig kan man h\u00e5ndtere terabyte af hukommelse. Jeg bruger stadig H2O. Af og til bruger jeg det i forskellige projekter \u2013 og det er stadig den hurtigste ting, der overg\u00e5r konkurrenterne med flere hundrede gange. Hvis du arbejder med Big Data med kolonnebaserede data, er det meget sv\u00e6rt at overg\u00e5 H2O.<\/p>\n<p><\/p>\n<h1 id=\"tehnicheskie-chellenzhi\">Technical challenges<\/h1>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Hvad har v\u00e6ret den st\u00f8rste udfordring i din karriere?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Diskuterer vi den tekniske eller ikke-tekniske del af sp\u00f8rgsm\u00e5let? Jeg vil sige, at de st\u00f8rste udfordringer ikke er tekniske.\u00a0<br \/>\nN\u00e5r det kommer til tekniske udfordringer, har jeg bare overvundet dem. Jeg ved endda ikke, hvilken der var den st\u00f8rste, men der var flere ret interessante, som tog ret lang tid og mental kamp. Da jeg gik til Sun, var jeg overbevist om, at jeg ville lave en hurtig compiler, mens mange seniorer sagde, at jeg aldrig ville lykkes. Men jeg tog den vej, skrev en compiler helt ned til registerallokatoren, og den var ret hurtig. Den var lige s\u00e5 hurtig som den moderne C1, men p\u00e5 det tidspunkt var allokatoren meget langsommere, og n\u00e5r jeg ser tilbage, var det et problem med den store datastruktur. Jeg havde brug for den for at skrive en grafisk registerallokator, og jeg forstod ikke dilemmaet mellem kodeudtrykkelse og hastighed, som eksisterede i den tid og var meget vigtig. Det viste sig, at datastrukturen normalt overskred cache-st\u00f8rrelsen p\u00e5 dengang x86-arkitekturen, og derfor, hvis jeg oprindeligt antog, at registerallokatoren ville bruge 5-10 procent af tiden p\u00e5 JIT, viste det sig i virkeligheden at v\u00e6re 50 procent. <\/p>\n<p><\/p>\n<p>Tiden gik, og compileren blev stadig mere pr\u00e6cis og effektiv, den holdt op med at generere frygteligt kode i flere tilf\u00e6lde, og ydeevnen begyndte mere og mere at ligne det, som C compileren leverede. Hvis du selvf\u00f8lgelig ikke skriver noget skrammel, som selv C ikke kan optimere. Hvis du skriver kode som i C, f\u00e5r du ogs\u00e5 ydeevne som i C i flere tilf\u00e6lde. Og jo l\u00e6ngere hen, desto oftere blev der produceret kode, der asymptotisk matchede C-niveau, registerallokatoren begyndte at ligne noget, der var f\u00e6rdigt... uanset om din kode k\u00f8rte hurtigt eller langsomt. Jeg fortsatte med at arbejde p\u00e5 allokatoren for at g\u00f8re den bedre til allokeringer. Den blev langsommere, men leverede stadig bedre ydeevne i de tilf\u00e6lde, hvor ingen kunne klare det. Jeg kunne dykke ind i registerallokatoren, begrave en m\u00e5neds arbejde der, og pludselig begyndte al koden at k\u00f8re 5% hurtigere. Det skete gang p\u00e5 gang, og registerallokatoren blev til en slags kunstv\u00e6rk \u2013 alle elskede eller hadede den, og akademikere stillede sp\u00f8rgsm\u00e5l som \"hvorfor er alt gjort p\u00e5 denne m\u00e5de\", hvorfor ikke. <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation#Linear_Scan\">line\u00e6r scanning<\/a><\/noindex>, og hvad forskellen er. Svaret er det samme: allocator baseret p\u00e5 graffarvning plus meget pr\u00e6cist arbejde med bufferkode er lig med et vinderredskab, den bedste kombination, som ingen kan overg\u00e5. Og det er en ret ikke-\u00e5benlys ting. Alt andet, som kompilatoren g\u00f8r der, er ret velkendte ting, selvom de ogs\u00e5 er blevet forfinet til kun kunstens niveau. Jeg har altid lavet ting, der skulle g\u00f8re kompilatoren til et kunstv\u00e6rk. Men intet af dette var noget ekstraordin\u00e6rt \u2013 bortset fra registerallokatoren. Pointen er, at man n\u00f8je <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Register_allocation\">skal afsk\u00e6re<\/a><\/noindex> under belastning, og hvis det sker (jeg kan forklare n\u00e6rmere, hvis det er interessant), betyder det, at man kan inlinje mere aggressivt uden risiko for at overskride performance-grafens brudpunkt. I de dage var der mange fuldskala kompilatorer, fyldt med funktioner og gadgets, der havde registerallokatorer, men ingen kunne g\u00f8re det igen. <\/p>\n<p><\/p>\n<p>Problemet er, at hvis du tilf\u00f8jer metoder, der kan indl\u00e6gges inline, og udvider og udvider omr\u00e5det for indligning, s\u00e5 overg\u00e5r det s\u00e6t af v\u00e6rdier, der bruges, straks antallet af registre, og man bliver n\u00f8dt til at spilde. Det kritiske niveau opst\u00e5r typisk, n\u00e5r allokatoren giver op, og en god kandidat til spild st\u00e5r over for en anden; man spilder nogle virkelig m\u00e6rkelige ting. V\u00e6rdien af indligning her ligger i, at du mister en del overhead, overhead p\u00e5 kald og lagring; du kan se v\u00e6rdierne indeni og kan optimere dem yderligere. Omkostningen ved indligning er, at der dannes et stort antal levende v\u00e6rdier, og hvis din registre-allokator spilder mere, end n\u00f8dvendigt, taber du straks. Derfor har de fleste allokatorer et problem: n\u00e5r indligningen overskrider en bestemt gr\u00e6nse, bliver alt spildt, og ydeevnen kan skyde i s\u00e6nk. Dem, der implementerer en compiler, tilf\u00f8jer nogle heuristikker: for eksempel at stoppe indligningen, n\u00e5r en vis st\u00f8rrelse er n\u00e5et, da allokationerne vil \u00f8del\u00e6gge alt. Det f\u00f8rer til et brud i ydeevnekurven \u2013 du indl\u00e6ser, indl\u00e6ser, ydeevnen stiger langsomt \u2013 og s\u00e5 bam! \u2013 den falder ned som en hurtig domkraft, fordi du har indl\u00e6st for meget. S\u00e5dan har det fungeret indtil Java kom. Java kr\u00e6ver meget mere indligning, s\u00e5 jeg m\u00e5tte g\u00f8re min allokator meget mere aggressiv, s\u00e5 det holder sig oppe i stedet for at falde. Og hvis du har indl\u00e6st for meget, begynder den at spilde, men s\u00e5 kommer der stadig et punkt, hvor der ikke er mere spild. Det er en interessant observation, som kom til mig ud af ingenting; det er ikke indlysende, men det har givet godt udbytte. Jeg tog fat p\u00e5 aggressiv indligning, og det f\u00f8rte mig til s\u00e5danne steder, hvor ydeevnen for Java og C g\u00e5r h\u00e5nd i h\u00e5nd. De er virkelig t\u00e6tte \u2013 jeg kan skrive kode i Java, der vil v\u00e6re betydeligt hurtigere end C-kode og s\u00e5 videre, men i gennemsnit, i det store billede, er de nogenlunde sammenlignelige. Jeg tror, at en del af denne fortjeneste ligger i registre-allokatoren, som tillader mig at indl\u00e6se s\u00e5 dumt som muligt. Jeg indl\u00e6ser bare alt, hvad jeg ser. Sp\u00f8rgsm\u00e5let er, om allokatoren fungerer godt, og om det resulterende kode er fornuftigt. Dette var en stor udfordring: at forst\u00e5 alt dette og f\u00e5 det til at fungere.<\/p>\n<p><\/p>\n<h1 id=\"nemnogo-pro-allokaciyu-registrov-i-mnogoyadernost\">A bit about register allocation and multi-core systems<\/h1>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Problemer som registrering allocation synes at v\u00e6re et evigt emne. Det er interessant, om der nogensinde har v\u00e6ret en id\u00e9, der s\u00e5 lovende ud, men som s\u00e5 fejlede i praksis?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Selvf\u00f8lgelig! Registrering allocation er et omr\u00e5de, hvor du pr\u00f8ver at finde nogle heuristikker for at l\u00f8se et NP-kompleks problem. Og du vil aldrig kunne opn\u00e5 en perfekt l\u00f8sning, ikke sandt? Det er simpelthen umuligt. Se, Ahead of Time-kompilering - det fungerer ogs\u00e5 d\u00e5rligt. Her handler diskussionen om nogle gennemsnitlige tilf\u00e6lde. Om typisk ydeevne, s\u00e5 du kan tage ud og m\u00e5le noget, du anser for at v\u00e6re god typisk ydeevne - i sidste ende arbejder du jo p\u00e5 at forbedre den! Registrering allocation er et emne, der helt er dedikeret til ydeevne. S\u00e5 snart du har den f\u00f8rste prototype, der fungerer og farver det, der er n\u00f8dvendigt, begynder arbejdet med ydeevnen. Du skal l\u00e6re at m\u00e5le godt. Hvorfor er det vigtigt? Hvis der er klare data, kan du kigge p\u00e5 forskellige omr\u00e5der og se: ah, det hjalp her, men der er det hele g\u00e5et galt! Der opst\u00e5r nogle gode id\u00e9er, du tilf\u00f8jer en ny heuristik, og pludselig begynder alt at fungere lidt bedre i gennemsnit. Eller det g\u00f8r det ikke. Jeg har haft mange tilf\u00e6lde, hvor vi k\u00e6mpede for fem procent ydeevne, der adskilte vores udvikling fra den tidligere allocator. Og hver gang ser det s\u00e5dan ud: et sted vandt, et sted tabte. Hvis du har gode v\u00e6rkt\u00f8jer til at analysere ydeevne, kan du finde de tabte id\u00e9er og forst\u00e5, hvorfor de taber. M\u00e5ske er det bedst at lade det v\u00e6re som det er, eller m\u00e5ske er det tid til en mere seri\u00f8s tilgang til finjustering, eller at g\u00e5 og fixe noget andet. Det er en hel r\u00e6kke ting! Jeg lavede denne seje hack, men jeg har brug for ogs\u00e5 den, og den, og den - og deres samlede kombination giver nogle forbedringer. Ensomme kan fejle. S\u00e5dan er naturen ved at arbejde med ydeevnen af NP-komplekse problemer.<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Det f\u00f8les som om, at ting som farvning i allocators er en allerede l\u00f8st opgave. N\u00e5, for dig ser det ud til at v\u00e6re l\u00f8st, hvis man ser p\u00e5 hvad du fort\u00e6ller, s\u00e5 er det s\u00e5 v\u00e6rd at...?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Det er ikke l\u00f8st som s\u00e5dan. Det er dig, der skal g\u00f8re det til en \"l\u00f8st\" problem. Der er sv\u00e6re opgaver, og de skal l\u00f8ses. N\u00e5r det er gjort, er det tid til at arbejde p\u00e5 ydeevne. Dette arbejde skal tages seri\u00f8st \u2013 lave benchmarks, samle metrikker, forklare situationer, hvor dit gamle hack begyndte at fungere igen (eller omvendt, stoppede med at fungere), n\u00e5r du ruller tilbage til en tidligere version. Og ikke give op, f\u00f8r du opn\u00e5r noget. Som jeg allerede har sagt, hvis der er fede ideer, der ikke fungerede, men inden for registrering allocation er ideerne ret uendelige. Du kan for eksempel l\u00e6se videnskabelige publikationer. Selvom dette omr\u00e5de i \u00f8jeblikket bev\u00e6ger sig langsommere og er blevet mere klart end i sin ungdom, arbejder der stadig en hel uendelighed af mennesker p\u00e5 dette omr\u00e5de, og alle deres ideer er v\u00e6rd at pr\u00f8ve; de venter bare p\u00e5 deres tid. Og du kan ikke sige, hvor gode de er, medmindre du pr\u00f8ver dem. Hvor godt de integreres med alt andet i din allocator, eftersom allocatoren laver mange ting, og nogle ideer i din specifikke allocator vil ikke fungere, mens de i en anden allocator g\u00f8r det uden problemer. Den prim\u00e6re m\u00e5de at vinde for en allocator er at tr\u00e6kke langsomme ting uden for den prim\u00e6re bane og tvinge dem til at splitte langs gr\u00e6nserne for de langsomme veje. S\u00e5 hvis du \u00f8nsker at starte GC, tage den langsomme rute, deoptimere, kaste undtagelser, alt i den stil \u2013 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 veje, men det er ikke s\u00e5 vigtigt, fordi de er langsomme, og der f\u00e6rdes sj\u00e6ldent folk der. For eksempel, en nulpeger \u2013 det sker aldrig, vel? Du skal have flere veje til forskellige ting, men de m\u00e5 ikke blandes p\u00e5 den prim\u00e6re rute.\u00a0<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: Hvad synes du om multicore, n\u00e5r der er tusind kerner? Er det en nyttig ting?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Succesen med GPU'en viser, at det er ret nyttigt!<\/p>\n<p><\/p>\n<p><strong>Vladimir<\/strong>: De er ret specialiserede. Og hvad med procesorer til almindeligt brug?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: N\u00e5, det var forretningsmodellen for Azul. Svaret kom i en tid, hvor folk virkelig satte pris p\u00e5 forudsigelig ydeevne. Dengang var det sv\u00e6rt at skrive parallelt kode. H2O-kodningsmodellen skalerer godt, men den er ikke en generel model. Den er kun lidt mere generel end ved brug af GPU. Taler vi om kompleksiteten ved at udvikle s\u00e5dan noget eller kompleksiteten ved at bruge det? For eksempel, en interessant lektie, som Azul l\u00e6rte mig, noget ret uventet: sm\u00e5 caches er helt okay.\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>: Hvad med de ikke-tekniske udfordringer?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>: Den st\u00f8rste udfordring var at undg\u00e5 at v\u00e6re... venlig og god mod folk. Som f\u00f8lge heraf befandt jeg mig konstant i ekstremt konfliktfyldte situationer. Situationen, hvor jeg vidste, at alt gik galt, men ikke vidste, hvordan jeg skulle komme videre med at l\u00f8se disse problemer, og jeg kunne ikke h\u00e5ndtere dem. Mange langvarige problemer, der har varet i \u00e5rtier, opstod p\u00e5 netop den m\u00e5de. Det faktum, at der i Java findes kompilatorer C1 og C2, er en direkte f\u00f8lge af dette. At der i Java i mange \u00e5r ikke var flerniveau kompilering, er ogs\u00e5 en direkte f\u00f8lge. Det er \u00e5benlyst, at vi havde brug for et s\u00e5dant system, men det er ikke \u00e5benlyst, hvorfor det ikke eksisterede. Jeg havde problemer med en ingeni\u00f8r\u2026 eller en gruppe af ingeni\u00f8rer. For mange \u00e5r siden, da jeg begyndte at arbejde i Sun, var jeg\u2026 N\u00e5, ikke kun dengang, jeg har generelt altid min egen mening om alting. Og jeg ans\u00e5 det for sandhed, at man bare kunne tage sin egen sandhed og fort\u00e6lle den direkte. Is\u00e6r da jeg var chokerende rigtig det meste af tiden. Og hvis du ikke kan lide denne tilgang\u2026 is\u00e6r hvis du \u00e5benlyst tager fejl og laver noget sjusk\u2026 Generelt kunne sv\u00e6rt f\u00e5 mennesker tolerere en s\u00e5dan kommunikationsform. Selvom nogle kunne, for eksempel jeg. Jeg har bygget hele mit liv p\u00e5 meritokratiske principper. Hvis du viser mig noget, der er forkert, vil jeg straks sige: du har sagt noget forkert. Samtidig undskylder jeg selvf\u00f8lgelig, og alt det der, anerkender fortjenester, hvis der er nogen, og g\u00f8r andre rigtige handlinger. P\u00e5 den anden side har jeg chokerende ret i chokerende stor procentdel af den tid, jeg interagerer med folk. Og det fungerer ikke s\u00e6rlig godt i relationer. Jeg pr\u00f8ver ikke at v\u00e6re venlig, men stiller problemet direkte. \u201cDet her vil aldrig fungere, fordi 1, 2 og 3\u201d. Og de er s\u00e5dan: \u201c\u00c5h!\u201d Der var ogs\u00e5 andre konsekvenser, som det nok er bedst at springe over: for eksempel der f\u00f8rte til skilsmisse fra min kone og ti \u00e5r med depression efterf\u00f8lgende.<\/p>\n<p><\/p>\n<p>En udfordring er at k\u00e6mpe mod folk og deres opfattelse af, hvad du kan eller ikke kan g\u00f8re, hvad der er vigtigt, og hvad der ikke er. Der har v\u00e6ret mange udfordringer omkring kodningsstil. Jeg skriver stadig meget kode, og dengang m\u00e5tte jeg endda bremse mig selv, fordi jeg lavede for mange parallelle opgaver og gjorde dem d\u00e5rligt, i stedet for at fokusere p\u00e5 \u00e9n ting. N\u00e5r jeg ser tilbage, har jeg skrevet halvdelen af koden til Java JIT-teamet, C2-teamet. Den n\u00e6ste hurtigste koders skrev halvt s\u00e5 hurtigt, den n\u00e6ste yderligere halvt s\u00e5 hurtigt, og det var en eksponentiel nedgang. Den syvende person i r\u00e6kken var meget, meget langsom \u2013 s\u00e5dan er det altid! Jeg har set p\u00e5 en masse kode. Jeg kiggede p\u00e5, hvem der skrev hvad, uden undtagelser, jeg kiggede ind i deres kode, gennemgik dem alle, og jeg fortsatte stadig med at skrive mere, end nogen af dem. Denne tilgang virker ikke s\u00e5 godt med folk. Nogle kan ikke lide det. Og n\u00e5r de ikke kan h\u00e5ndtere det, opst\u00e5r der alle mulige klager. For eksempel blev jeg engang bedt om at stoppe med at skrive kode, fordi jeg skriver for meget kode, og det truede teamet. Det l\u00f8d for mig som en joke: Hvis hele resten af teamet forsvinder, og jeg forts\u00e6tter med at skrive kode, vil du kun miste halvdelen af teamet. P\u00e5 den anden side, hvis jeg forts\u00e6tter med at skrive kode, og du mister halvdelen af teamet \u2013 det lyder som meget d\u00e5rlig ledelse. Jeg har aldrig t\u00e6nkt s\u00e5 meget over det, aldrig talt om det, men det var alligevel et sted i mit sind. En tanke, der k\u00f8rte rundt i baghovedet: \"Er I alle sammen p\u00e5 sp\u00f8g?\". S\u00e5 den st\u00f8rste udfordring var mig og mine relationer til folk. Nu forst\u00e5r jeg mig selv meget bedre, jeg har v\u00e6ret teamleder for programm\u00f8rer i lang tid, og nu siger jeg direkte til folk: Du ved, jeg er s\u00e5dan, som jeg er, og I bliver n\u00f8dt til at h\u00e5ndtere det \u2013 er det okay, at jeg st\u00e5r her? Og n\u00e5r de har l\u00e6rt at h\u00e5ndtere det, s\u00e5 fungerer det hele. Jeg er jo hverken d\u00e5rlig eller god, jeg har ikke d\u00e5rlige intentioner eller egoistiske str\u00e6ben, det er bare min essens, og man m\u00e5 finde en m\u00e5de at leve med det p\u00e5.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: For nylig er alle begyndt at tale om selvbevidsthed for indadvendte og generelt om bl\u00f8de f\u00e6rdigheder. Hvad kan man sige om det?<\/p>\n<p><\/p>\n<p><strong>Cliff<\/strong>Ja, det var en forst\u00e5else og en lektie, jeg fik ud af min skilsmisse med min kone. Hvad jeg fik ud af skilsmissen \u2013 det var en forst\u00e5else af mig selv. S\u00e5dan begyndte jeg at forst\u00e5 andre mennesker. Forst\u00e5, hvordan denne interaktion fungerer. Det f\u00f8rte til opdagelser en efter en. Der kom en bevidsthed om, hvem jeg er, og hvad jeg repr\u00e6senterer. Hvad jeg g\u00f8r: enten er jeg optaget af opgaven, eller jeg undg\u00e5r konflikten, eller noget andet \u2013 og et s\u00e5dant niveau af selvbevidsthed hj\u00e6lper virkelig med at holde sig selv i skak. Efter dette g\u00e5r alt meget lettere. En ting, jeg har opdaget ikke kun hos mig selv, men ogs\u00e5 hos andre programm\u00f8rer \u2013 er umuligheden af at verbalisere tanker, n\u00e5r man er under f\u00f8lelsesm\u00e6ssig stress. For eksempel, du sidder og koder, er i en flowtilstand, og s\u00e5 kommer nogen l\u00f8bende og begynder at skrige hysterisk, at noget er brudt sammen, og nu vil man tage drastiske foranstaltninger. Og du kan ikke sige \u00e9t ord, fordi du er i en tilstand af f\u00f8lelsesm\u00e6ssig stress. Den viden, man har erhvervet, g\u00f8r det muligt at forberede sig p\u00e5 dette \u00f8jeblik, opleve det, og g\u00e5 videre til en tilbagetr\u00e6kningsplan, hvorefter man kan g\u00f8re noget. S\u00e5 ja, n\u00e5r man begynder at forst\u00e5, hvordan det hele fungerer \u2013 er det en k\u00e6mpe livs\u00e6ndrende begivenhed.\u00a0<br \/>\nJeg kunne ikke selv finde de rigtige ord, men jeg husker sekvensen af handlinger. Essensen er, at denne reaktion er lige s\u00e5 fysisk som den er verbal, og du har brug for plads. En s\u00e5dan plads, i zen-forstand. Det er pr\u00e6cis det, der skal forklares, og s\u00e5 straks tr\u00e6de til side \u2013 fysisk tr\u00e6de til side. N\u00e5r jeg er stille med ord, kan jeg bearbejde situationen i forhold til f\u00f8lelser. Som adrenalinen n\u00e5r hjernen, skifter det dig til \"fight or flight\"-tilstand, s\u00e5 kan du ikke sige noget, nej \u2013 nu er du en idiot, en punchline-ingeni\u00f8r, ude af stand til at give et v\u00e6rdigt svar eller stoppe angrebet, og angriberen kan frit angribe igen og igen. Man skal f\u00f8rst blive sig selv igen, genvinde kontrollen, komme ud af \"fight or flight\"-tilstand. <\/p>\n<p><\/p>\n<p>Og derfor er der behov for et verbalt rum. Bare et frit rum. Hvis man overhovedet skal sige noget, kan man netop h\u00e6vde dette, og s\u00e5 g\u00e5 ud og finde sit \"rum\": g\u00e5 en tur i parken, l\u00e5se sig inde i bruseren \u2013 det er ligegyldigt. Det vigtigste er at koble midlertidigt fra den situation. S\u00e5 snart du kobler fra, selv i et par sekunder, kommer kontrollen tilbage, og du begynder at t\u00e6nke klart. \"Godt, jeg er ikke nogen idiot, jeg laver ikke dumme ting, jeg er et ret nyttigt menneske.\" S\u00e5 snart du kan overbevise dig selv om dette, er det tid til at g\u00e5 videre til n\u00e6ste trin: forst\u00e5, hvad der skete. Du blev angrebet, angrebet kom fra et uventet sted, det var en usportslig baghold. Det er d\u00e5rligt. N\u00e6ste skridt er at forst\u00e5, hvorfor angriberen havde brug for det. Virkelig, hvorfor? M\u00e5ske fordi han selv er rasende? Hvorfor er han rasende? For eksempel fordi han selv har fejlet og ikke kan tage ansvar? P\u00e5 den m\u00e5de skal man forsigtigt bearbejde hele situationen. Men for dette kr\u00e6ves der plads til man\u00f8vrering, verbalt rum. Det f\u00f8rste skridt er at bryde det verbale kontakt. G\u00e5 v\u00e6k fra ords diskussion. Annuller det, g\u00e5 hurtigt v\u00e6k. Hvis det er en telefonopkald \u2013 l\u00e6g simpelthen r\u00f8ret p\u00e5 \u2013 det er en f\u00e6rdighed, jeg har l\u00e6rt fra mine samtaler med min tidligere kone. Hvis samtalen ikke f\u00f8rer til noget godt, s\u00e5 sig bare \"farvel\" og l\u00e6g r\u00f8ret p\u00e5. P\u00e5 den anden side siger de: \"bla-bla-bla\", og du svarer: \"aha, farvel!\" og l\u00e6gger p\u00e5. Du stopper simpelthen samtalen. Fem minutter senere, n\u00e5r din evne til at t\u00e6nke klart kommer tilbage, er du lidt k\u00f8let ned, og det bliver muligt at overveje, hvad der egentlig skete og hvad der vil ske n\u00e6ste gang. Og begynde at formulere et gennemt\u00e6nkt svar i stedet for blot at reagere ud fra f\u00f8lelser. For mig var gennembruddet i selvbevidsthed netop det, at jeg i tilf\u00e6lde af f\u00f8lelsesm\u00e6ssigt stress ikke kan tale. At komme ud af denne tilstand, overveje og planl\u00e6gge hvordan man skal svare og kompensere for problemer \u2013 det er de rigtige skridt, n\u00e5r man ikke kan tale. Den enkleste m\u00e5de er at flygte fra situationen, hvor f\u00f8lelsesm\u00e6ssigt stress opst\u00e5r, og simpelthen stoppe med at deltage i dette stress. Efter dette genvinder du evnen til at t\u00e6nke, n\u00e5r du kan t\u00e6nke, og mulighederne for at tale osv.<\/p>\n<p><\/p>\n<p>Faktisk fors\u00f8ger modpartens advokat at g\u00f8re dette med dig i retten \u2013 nu er det klart, hvorfor. Fordi han har mulighed for at presse dig til et punkt, hvor du ikke engang kan sige dit eget navn, for eksempel. I ordets mest direkte forstand, kan du ikke tale. Hvis du oplever dette og ved, at du vil v\u00e6re et sted, hvor der er verbale kampe, et sted som retten, s\u00e5 kan du tage din advokat med. Advokaten vil beskytte dig og stoppe den verbale angreb, og han vil g\u00f8re det p\u00e5 en helt lovlig m\u00e5de, og du vil f\u00e5 dit tabte zenrum tilbage. For eksempel, jeg m\u00e5tte et par gange ringe til familien, dommeren var ganske venlig, men modpartens advokat skreg og skreg af mig, jeg kunne ikke selv f\u00e5 et ord ind. I s\u00e5danne tilf\u00e6lde fungerer det bedst for mig at bruge en m\u00e6gler. M\u00e6gleren stopper det tryk, der str\u00f8mmer over dig som en konstant str\u00f8m, du genfinder det n\u00f8dvendige zenrum, og sammen med det vender evnen til at tale tilbage. Dette er et helt omr\u00e5de af viden, hvor man skal l\u00e6re meget, opdage meget inden i sig selv, og alt dette f\u00f8rer til h\u00f8jtst\u00e5ende strategiske beslutninger, der varierer fra person til person. Nogle har ikke de omtalte problemer, typisk har folk, der professionelt arbejder med salg, ikke disse problemer. Alle disse mennesker, der lever af ord \u2013 kendte sangere, digtere, religi\u00f8se ledere og politikere, de har altid noget at sige. De har ikke s\u00e5danne problemer, men jeg har.<\/p>\n<p><\/p>\n<p><strong>Andrey<\/strong>: Det var... uventet. Godt, vi har allerede snakket en del, og det er tid til at afslutte dette interview. Vi ses absolut p\u00e5 konferencen, og vi kan forts\u00e6tte denne dialog. Vi ses p\u00e5 Hydra!<\/p>\n<p><\/p>\n<blockquote><p>Du kan forts\u00e6tte samtalen med Cliff ved konferencen Hydra 2019, der finder sted den 11.-12. juli 2019 i Sankt Petersborg. Han kommer med et foredrag <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 k\u00f8bes <noindex><a rel=\"nofollow\" href=\"https:\/\/hydraconf.ru\/?utm_source=habr&amp;utm_medium=458718\">p\u00e5 den officielle hjemmeside<\/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.3 - 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\/da\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47 Stort interview med Cliff Click \u2014 far til JIT-compilation i Java | ProHoster","description":"Cliff Click \u2014.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/bolshoe-intervyu-s-kliffom-klikom-ottsom-jit-kompilyatsii-v-java","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/35851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=35851"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/35851\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=35851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=35851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=35851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}