Min bedste laptop

Jeg faldt i en artikel om produktion af moderne halvledere, om de relative fordele/ulemper ved 10nm hhv. 7nm processerne.

Forfatteren svinger om sig med forkortelser som om en politiker med valgløfter, men hvis man tager tiden er der nogle meget vigtige pointer, både på og imellem linierne.

Grundlæggende set foregår halvlederproduktion stadig med masker der gennemlyses og i takt med at transistorer og ledninger er blevet mindre, er lyset blevet mere og mere ultraviolet og fysikken mere og mere påtrængende.

Den nuværende process bruger lys med en bølgelængde på 193nm og allerede her burde folk der har hørt efter i fysiktimen spidse ørene: Hvordan laver man 32nm brede streger med 193nm lys ?

Svaret er at det gør man også kun med nød og næppe, ofte involverer det fire forskellige masker der skal belyses efter hinanden for et enkelt lag i halvlederen.

Løsningen på det problem skulle have været "Extreme Ultra Violet", bølgelængder omkring 13.5 nm, noget mange fysikere ville opfatte som "blød röngtenstråling."

Man var klar over at det blev en "nasty" og fra de første experimenter i midten af 1990'erne til nu er listen over problemer bare blevet længere og længere og listen med løsninger har svært ved at følge med. Læs f.eks Wikipedias artikel om EUV.

Den "soundbite" fra den oprindelige artikel der sprang mig i øjnene var flg: "In fact, it costs $271 million to design a 7nm system-on-a-chip, which is about nine times the cost to design a 28nm device".

Indtil nu har halvlederbranchen nogenlunde kunnet følge med Moores lov på en eller anden måde: Hvert andet eller tredje år har man ganget nanometerne med 0.7 således at der kom dobbelt så mange transistorer på samme areal, resulterende i lavere priser, lavere effektforbrug og indtil for et årti siden: højere hastighed.

Først fladede hastigheden ud, fordi faststoffysikken kom i vejen.

Derefter fladede effektforbruget ud, fordi faststoffysikken kom i vejen.

Og endelig er det nu prisen der ikke kan forbedres mere.

Det betyder ikke at Moores lov er død men blot at prisen stiger ude af proportioner med performance.

Og nej, "Flere cores" løser ikke problemet, når problemet er prisen per transistor.

Eller sagt på en anden måde: Indtil der sker et virkeligt gennembrud i faststoffysikken bliver min laptop ikke bedre end nu.

At hardwaren stagnerer får konsekvenser.

På softwaresiden vil det naturligvis stadig være muligt at "smide mere CPU efter problemet", men det bliver en dyr løsning.

Hvis min næste computer ikke bliver synligt bedre end den nuværende forsvinder argumentet for de korte levetider: Fremtidens hardware skal simpelthen holde længere for de samme penge.

Det betyder igen færre kasser, men for leverandører der kan levere bedre levetid, flere penge per kasse.

I server segmentet vil der blive fokus på om andre instruktionssæt end x86 er en bedre forretning, primært ARM64, men MIPS, Power og SPARC er i princippet også i spil - hvis nogen har råd til at experimentere til $271M/stykket.

Men frem for alt betyder det at faststoffysikken ikke løser IT-branchens CO2 problem.

Allerede nu estimeres CO2-forureningen fra IT-branchen på højde med flytrafikkens.

Med Paris aftalen underskrevet vil det ikke gå upåagtet hen ret længe.

phk

Kommentarer (29)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Claus Juul

I forhold til ydelse, bliver det spændende at se om asymmetriske cores kan løfte noget af opgaven med den oplevede performance.

Jeg tænker på en processer der måske har 3-4 traditionelle cores, 1-2 gpu cores, 1-2 fysik cores og måske 1 lille quntom processer del

Lars Juul

Det bliver spændende at se hvor meget Intel får ud af deres opkøb af Altera, og i hvor høj grad man kan anvende et FPGA fabric i en "general purpose" processor, herunder samspillet med software og compilere.

Poul-Henning Kamp Blogger

Intels FPGA planer er rettet mod nogle meget specifikke kunder og erfaringen siger at overhead med at tage turen ud i FPGA og tilbage sjældent kan betale sig.

Undtagelseene er rekonfigurerbare krypteringsalgoritmer og regexp-in-hardware - hvilket giver dig en god ide om hvilke "specifikke kunder" der er tale om.

Troels Henriksen

Denne udvikling betyder at effektiv kode begynder at blive en nødvendighed på en helt anden måde end det tidligere har været - overalt.

I betragtning af at der næppe kommer til at ske nogen stor forbedring af den gennemsnitlige programmørs evner, så bliver det interessant at se hvordan det vil flaske sig. Nye og specialiserede sprog der er nemmere at optimere automatisk?

Torben Mogensen Blogger

Udviklingen op gennem 90'erne og 00'erne var at smide mange transistorer efter en enkelt core: Spekulativ udførsel, avanceret branch prediction, et stort scheduling window, store caches, osv. Selv nu, hvor tendensen mere er mod flere og flere kerner, har hver enkelt kerne stadig mange transistorer, hvis primære formål er at få denne enkelte kerne til at køre hurtigt, specielt for at undgå, at den skal vente på data, og ikke laver noget imens.

Hvis man vil acceptere en halvering af den hastighed en enkelt kerne har, så kan man reducere dens størrelse til en fjerdedel eller mindre. Og forbedret software kan mindske skadevirkningerne: I stedet for at lave avanceret hopforudsigelse og andre analyser på køretid, kan man lave (knap så gode, men acceptable) analyser på oversættelsestid. Det kan måske kræve andre programmeringsmetodikker, f.eks. at gå fra eksplicit kodede løkker til vektoroperationer, at gå bort fra virtuelle metodekald, at undgå shared memory (som kræver en del hardware at holde konsistent), osv.

Generelt er der nok en del at hente på softwaresiden: De mest populære "virtuelle maskiner", JVM og .NET, er dårligt egnede til hurtig eksekvering, da de er bygget på en beregningsmodel, hvor mange beslutninger (indekscheck, typecheck, metodekald, null-pointercheck, osv) tages på køretid, så for at få performance, smider man avancerede køretidsoptimeringer efter dem, men det koster også. Endnu værre er al den software, der er skrevet i Javascript, Ruby, Perl, osv, som er endnu langsommere i deres udganspunkt, og som er endnu vanskeligere at optimere. God performance får man som udgangspunkt kun ved at undgå køretidscheck, og det gør man kun ved, at check kan verificeres under oversættelse eller helt undgås, hvis f.eks. null-pointere slet ikke kan forekomme i sproget.

Poul-Henning Kamp Blogger

God performance får man som udgangspunkt kun ved at undgå køretidscheck,

Mnjae... Men her render vi ind i en af de andre performance krav: Køretidschecks er en nødvendig, men ikke tilstrækkelig forudsætning for resistens mod hostile inputdata.

Umiddelbart er det største potientiale i alt det bloatede middleware og tåbelige historiske valg vi lider af.

F.eks er det rablende vanvittigt at det eneste sted X.509 overlever er i kryptografiske certifikater, man kunne spare nogle millioner ret skumle kodelinier ved at migrere til enten XML eller endnu bedre: JSON.

Peter Lind

Denne udvikling betyder at effektiv kode begynder at blive en nødvendighed på en helt anden måde end det tidligere har været - overalt.

Nej, det betyder at det bliver det igen. Det er ikke voldsomt mange år siden man gjorde alt hvad man kunne for at presse så meget effektivitet ud af hardwaren som muligt, simpelthen fordi hardwaren var begrænset.

Det var først da man gik til Windows 95/98 (for Windows-segmentet) at man begyndte at kunne ignorere hardware-begræsningerne ved bare at smide mere hardware efter problemet.

Claus Juul

Jeg tænkte ikke så specifikt, mere konceptuelt, som at INTEL og AMD har lagt understøttelse af forskellige opgaver ned i CPU'erne fx AMD's 3Dnow, kunne det være fordelagtigt at implementere cores der er super potente til at løse specifikke og tit anvendte beregnings opgaver, på samme "printplade" fx at blande den almindelige CPU core med en GPU core eller en FPGA core eller en quantum.

Der er ikke sikkert det giver mere performance, men den oplevede performance (effekt) kunne godt være højere.

Torben Mogensen Blogger

Køretidschecks er en nødvendig, men ikke tilstrækkelig forudsætning for resistens mod hostile inputdata.

Der vil selvfølgelig altid være behov for at checke inddata. Det er køretidstest, der i princippet er uafhængige af inddata (eller burde være det), jeg gerne så afskaffet. Det gælder f.eks. typechecks (som sker på køretid i de fleste scriptingssprog), null-pointerchecks (som laves i f.eks. JVM og .NET, fordi alle ikke-skalare typer per default kan være null-pointere), indexchecks (fordi man bruger eksplicitte løkker i stedet for vektoroperationer), downcasts (som ikke kan undgås i f.eks. JVM, når man bruger generiske typer eller arrays), osv.

Løsningen er ikke bare at slå alle disse checks fra. Man undgår måske det performancetab, de giver, men man mister også den sikkerhed, de giver. Det har historisk givet anledning til mange sikkerhedshuller.

Bjarne Nielsen

F.eks er det rablende vanvittigt at det eneste sted X.509 overlever er i kryptografiske certifikater, man kunne spare nogle millioner ret skumle kodelinier ved at migrere til enten XML eller endnu bedre: JSON.

X.509 beskriver formatet for certifikat baseret PKI, så det er ca. lige så meningsfuldt som at kritisere færdselsloven for kun at blive anvendt i trafikken.

Men måske tænker du på ASN.1 (X.680-683) eller rettere brugen af BER/DER (X.690)? ASN.1 kan - så vidt jeg ved - også encodes i XML format, men det har jeg ikke set nogen gøre. BER/DER er binære formater og egner sig glimrende til kryptografisk indhold, der som oftest af natur er binært - og det er IMHO ikke sværere at forstå end XML.

Vil man skulle rumme binært indhold i tekstformater som XML og JSON, så skal det encodes (f.eks. med base64, som i øvrigt også findes i flere udgaver - se f.eks. RFC7520 m.fl. om JSON encoding af kryptografi, som baserer sig på base64url, som beskrevet i RFC4648).

Repræsentation i BER/DER er mere kompakt end XML (og JSON), og det er nemt at skrive effektive parsere til det, da der er tale om et binært TLV format - så det ligger lige til højrebenet, når man arbejder med kryptografi - med XML og JSON vil der oftest blive kørt et standardbibliotek eller flere i stilling.

Selvom der er plads til forbedring, og selvom at jeg i situationer, hvor man godt må svine med ressourcerne, godt kunne overtales til at bruge de tekstbaserede formater, så synes jeg jo nok, at det er en anelse overdrevet at kalde det "rablende vanvittigt".

Morten Jensen

Det er køretidstest, der i princippet er uafhængige af inddata (eller burde være det), jeg gerne så afskaffet. Det gælder f.eks. typechecks (som sker på køretid i de fleste scriptingssprog), null-pointerchecks (som laves i f.eks. JVM og .NET, fordi alle ikke-skalare typer per default kan være null-pointere), indexchecks (fordi man bruger eksplicitte løkker i stedet for vektoroperationer), downcasts (som ikke kan undgås i f.eks. JVM, når man bruger generiske typer eller arrays), osv.

Jeg bruger en model-checker* til at verificere rigtig mange af mine assertions statisk i C kode. Det virker rigtig godt til embedded kode, idét udfaldsrummet / state space er begrænset og man dermed har reel mulighed for at analysere udtømmende. Specifikationerne kan kodes i C med assertions, og jeg har haft succes med at kode specifikationer i hjemmestrikket bounded LTL.

Frama-C bør også nævnes, og data-flow analysen (via Jessie-plugin'et) er rigtig god og kan analysere koden temmelig dybt; man får som regel også resultatet indenfor sekunder eller minutter.

Der findes rigtig kraftige værktøjer til statisk analyse af C, og endnu flere til Java. LLVM er temmelig nemt at skrive plugins til statisk analyse f.eks.

Jeg mener man pt. har alle værktøjer pt. til at udvikle bedre statisk analyse af f.eks. C-kode. Lige nu er vi bare dér, hvor der findes kommercielle løsninger til mange af de problemer du omtaler, men hvor Open Source-værktøjerne endnu ikke er helt så brugervenlige omend næsten lige så kapable.

Michael Cederberg

Det gælder f.eks. typechecks (som sker på køretid i de fleste scriptingssprog), null-pointerchecks (som laves i f.eks. JVM og .NET, fordi alle ikke-skalare typer per default kan være null-pointere), indexchecks (fordi man bruger eksplicitte løkker i stedet for vektoroperationer), downcasts (som ikke kan undgås i f.eks. JVM, når man bruger generiske typer eller arrays), osv.

null-pointer/ref checks er på ingen måde dyre. Det samme gælder til en hvis grad bounds-checks. Selv de simpleste processorer suser hen over dem. Jeg har meget svært ved at se det skulle give nogen målbar performance forøgelse. JVM'en er i øvrigt god til at optimere checks væk, sådan at der bliver ganske få.

I det hele taget tror jeg at hvis man tog JVM'ens statistikbaserede optimering (og alle de andre smarte ting den laver) og kombinerede med den meget stærkere type-model i .NET, så vil en JVM-CLR amalgamation komme tæt på eller overhale C/C++. Og selv hvis det er 25% langsommere betyder det ikke noget i langt de fleste tilfælde.

Man skal ikke undervurdere værdien af at kunne optimere libraries efter hvordan de rent faktisk bliver brugt, og ikke bare ud fra statisk analyse.

Noget helt andet er så at rigtigt mange udviklere fuldstændigt har glemt at vælge fornuftige algoritmer. Mod det hjælper ingen compiler eller CPU optimering ...

David Christensen

I det hele taget tror jeg at hvis man tog JVM'ens statistikbaserede optimering (og alle de andre smarte ting den laver) og kombinerede med den meget stærkere type-model i .NET, så vil en JVM-CLR amalgamation komme tæt på eller overhale C/C++.

Kun indtil du overvejer, at alle C og C++-compilere, der er worth their salt, understøtter profilbaseret optimering (eller guided optimization som det også kaldes), hvor du samler profildata under afvikling af softwaren, og bruger denne som empiri til at identificere bottlenecks og hot spots, og dermed bruger betydeligt mere krudt på at optimere disse i compile-fasen.

Udfordringen er naturligvis, at denne optimeringsprofil afhænger af den konkrete mikroarkitektur (der er milevidt mellem en ny Intel Sky Lake og en ældre Sandy Bridge—for slet ikke at tale om en AMD-processor), men der er i flere og flere styresystemer understøttelse for "fat binaries" som kan indeholde mere og mere fine-grained separerede binaries, som kan "strippes ud" under installation. Ved open source-projekter kan sådan profildata jo også bundles med kildekoden og den rigtige vælges i konfigurationsfasen.

Så klart, det er lidt "smartere" med en JIT-compiler, fordi den i sagens natur ved præcis hvad den kører på, men de performance gains du rigtigt peger ud, er også mulige med klassiske ahead-of-time compilere.

Troels Henriksen

Derudover har JIT-oversættere andre problemer:

  • De er under større resursepres end traditionelle oversættere, så mange effektive (men dyre) optimeringer er ikke realistiske.

  • De opererer typisk på lavniveau-represæntationer (oversat bytecode), hvilket betyder at mange invarianter fra det oprindelige programmeringssprog er forsvundet. F.eks. man man i et rent funktionssprog relativt lave mange aggressive transformationer, såsom fusion, der slet ikke er realistiske at udføre på lavniveau bytecode.

  • En JIT opererer typisk lokalt, og kan f.eks. ikke ændre på datastruktur-repræsentationer. En helprograms-optimerende oversætter kan lave globale ændringer.

Det er sigende at ingen af de eksisterende high-performance sprog er JITede. En JIT er mest nyttig hvis man har et dynamisk sprog, hvor JITen kan bruges til at bortoptimere noget af omkostningen ved den dynamiske opførsel, ved at den observerer hvilken konkret adfærd programmet egentlig har ved køretid og genererer specialiseret kode dertil.

Michael Cederberg

Udfordringen er naturligvis, at denne optimeringsprofil afhænger af den konkrete mikroarkitektur (der er milevidt mellem en ny Intel Sky Lake og en ældre Sandy Bridge—for slet ikke at tale om en AMD-processor), men der er i flere og flere styresystemer understøttelse for "fat binaries" som kan indeholde mere og mere fine-grained separerede binaries, som kan "strippes ud" under installation. Ved open source-projekter kan sådan profildata jo også bundles med kildekoden og den rigtige vælges i konfigurationsfasen.

Så klart, det er lidt "smartere" med en JIT-compiler, fordi den i sagens natur ved præcis hvad den kører på, men de performance gains du rigtigt peger ud, er også mulige med klassiske ahead-of-time compilere.

Næsten helt enig. JIT compileren kan skifte strategi alt efter hvordan programmet kører netop denne gang. Det betyder at den har noget mere viden.

De er under større resursepres end traditionelle oversættere, så mange effektive (men dyre) optimeringer er ikke realistiske.

Det er ikke rigtigt. JIT compilen kan have mange passes, hvor koden progressivt bliver mere optimeret. Sådan virker JVM'en. Koden starter med at køre med det samme - i starten rent fortolket. Der behøver således ikke være noget ressourcepres.

De opererer typisk på lavniveau-represæntationer (oversat bytecode), hvilket betyder at mange invarianter fra det oprindelige programmeringssprog er forsvundet. F.eks. man man i et rent funktionssprog relativt lave mange aggressive transformationer, såsom fusion, der slet ikke er realistiske at udføre på lavniveau bytecode.

Såfremt det er nødvendigt kan man reversecompile bytecode/p-code/IL til det oprindelige sprog næsten uden ændringer. Dette indikerer at hvis man kender til den oprindelige compiler og "mellemkoden" så er der (næsten) intet tab af information. I hvilket omfang dette udnyttes ved jeg ikke.

En JIT opererer typisk lokalt, og kan f.eks. ikke ændre på datastruktur-repræsentationer. En helprograms-optimerende oversætter kan lave globale ændringer.

Jeg skal ikke kunne sige i hvilket omfang det sker, men jeg kan ikke se der er noget der forhindrer en JIT i at gøre det samme. Og i og med mange libraries shippes som dynamic/shared så bliver din helprograms optimerende oversætter kun partiel. Man kan selvfølgeligt linke det hele statisk, men det er ikke normalen.

Det er sigende at ingen af de eksisterende high-performance sprog er JITede

Der er ingen der siger at det bliver ved med at være sådan. Der er sket meget på JIT siden. Men der er på den anden side heller ingen grund til at C++ ikke kan JITtes. Der er dog nogle konstruktioner i "wild-west-pointer" sprog der kan være svære at optimere.

En JIT er mest nyttig hvis man har et dynamisk sprog, hvor JITen kan bruges til at bortoptimere noget af omkostningen ved den dynamiske opførsel, ved at den observerer hvilken konkret adfærd programmet egentlig har ved køretid og genererer specialiseret kode dertil.

Det er jeg ganske uenig i. En JITter har det meget nemmere med stærkt typede sprog. For så er der meget mere information til at generere den endelige kode. Og det at observere konkret adfærd ved køretid og optimere derefter gælder for alle sprog.

Torben Mogensen Blogger

En JITter har det meget nemmere med stærkt typede sprog. For så er der meget mere information til at generere den endelige kode.

Du mener formentligt statisk typede sprog. Dynamiske sprog kan godt være stærkt typede. Statisk/dynamisk: Før køretid/under køretid. Stærkt/svagt: Alle typefejl opdages/nogen typefejl opdages ikke. F.eks. er C statisk og svagt typet, mens Scheme er dynamisk og stærkt typet. Java er stærk typet, men delvist dynamisk.

Men det er ikke kun JIT, der har glæde af statiske typer, det har traditionel offline oversættelse også. Generelt er statiske typer en fordel både for effektiv kodegenerering (uanset metode), som et middel til at opdage programmeringsfejl tidligt, og som en guide til at strukturere sine data og sit program (type-driven programming). Stort set den eneste ulempe er, at man skal skrive typerne og omskrive dem, når de ændrer sig. Men det kan man med typeinferens (næsten) undgå.

Troels Henriksen

Jeg snakkede nu ikke om statiske versus dynamiske typer, men om dynamisk adfærd - f.eks. virtuelle eller indirekte metodekald. JITs er gode til at optimere disse, men mindre gode til strukturelle transformationer.

Såfremt det er nødvendigt kan man reversecompile bytecode/p-code/IL til det oprindelige sprog næsten uden ændringer.

Det tror jeg ikke på - i hvert fald ikke hvis det oprindelige sprog har stærke invarianter (såsom immutabilitet eller højniveau-kontrolstrukturer), og du gerne vil genskabe disse invarianter ud fra bytekoden. Man kan i hvert fald ikke med nogen af de bytekodeformater jeg har set.

Michael Cederberg

Det tror jeg ikke på - i hvert fald ikke hvis det oprindelige sprog har stærke invarianter (såsom immutabilitet eller højniveau-kontrolstrukturer), og du gerne vil genskabe disse invarianter ud fra bytekoden. Man kan i hvert fald ikke med nogen af de bytekodeformater jeg har set.

Jeg kan selvfølgeligt ikke love dig at det gælder for alle sprog og alle konstruktioner. Men det gælder for både java og C# som de respektive bytekodeformater er designet til. Fx. kan man på C# reversecompilere både lambdas, enumerators og await konstruktioner.

JITs er gode til at optimere disse, men mindre gode til strukturelle transformationer.

Jeg tror du må komme med nogle eksempler.

Michael Cederberg

Loop fusion, loop interchange, vektorisering (til dels - visse JITs kan vistnok i enkle tilfælde hvis kildeteksten er tilpas annoteret), accelerator offload (a la OpenMP/OpenACC) og global registerallokering.

Endnu engang har jeg svært ved at se hvilke af ovenstående som ikke lader sige gøre i en JIT compiler. Vi kan godt blive enige om at det er begrænset hvor mange der laves i dagens JIT compilere. Men det er også optimeringer der hvor værdien er reduceret i forhold til mere klassiske optimeringer (fordi alle vælger de optimeringer som giver mest først). Vigtigere: der er ikke noget der forhindrer en JIT compiler i at lave den slags. Den har (næsten) den samme mængde statisk information til rådighed plus statistik fra kørsel.

Vi kan selvfølgeligt putte mere avancerede konstruktioner ind i sprogene til at håndtere heterogene systemer (á la mainframe I/O processorer eller GPU’er) eller andre koncepter (fx message parsing). I de tilfælde vil bytekoden ligesom sproget i nogen tilfælde skulle udvides for at repræsentere dette. Bytekoden bør ikke være mejslet i sten (selvom det har været forsøgt med JVM’en – fx ledte dette til den idiotiske implementering af generics i Java).

Global registerallokering er ganske vist ikke en strukturel transformation, men til gengæld et andet eksempel på en optimering der ikke rigtigt lader sig gøre i en JIT.

Det mener jeg godt det kan. Så snart JVM’en har identificeret en blok som ”hot” så kunne den i princippet sætte en klassisk compiler til at recompilere netop den blok med alle de tricks den har. Endnu bedre kunne den så også tage den statistik den allerede har samlet og bruge den sammen med. En sådan superoptimeret blok kan være arbitrært stor.

Jeg se umiddelbar to problemer som JIT compileren har som en klassisk ahead-of-time compiler ikke har:

  • Indsamling af statistik koster noget. Og så længe JIT compileren har truffet compile valg pga. statistik, er den nødt til at forsætte med indsamling af statistik, i tilfælde at situationen ændrer sig.

  • Generering af maskinkode som kan replaces on-the-fly. Moderne CPU gør dog at de få ekstra instruktioner har meget lille indflydelse på kørselstiden.

Overdrevent brug af virtual dispatch i sprog som Java og (i mindre grad) C# har også været et problem. Men som du selv nævner er nogen VM’er (læs JVM’en) blevet gode til at optimere den slags. Overdrevent brug af virtual dispatch er dog problem i sprogene og ikke et problem ved JIT compilering som sådan.

Torben Mogensen Blogger

der er ikke noget der forhindrer en JIT compiler i at lave den slags.

I princippet ikke. Men den tid, en JIT compiler bruger på optimeringer, går ud over køretiden. En offline compiler kan bruge meget mere tid på optimeringer end en gennemsnitstiden for en enkelt kørsel af programmet. Hvis en JIT compiler gjorde dette, ville det være et nettotab. Så det er ikke sådan, at en JIT compiler ikke kan lave globale transformationer m.m., men det vil normalt ikke være en fordel.

Jesper Louis Andersen

Jeg se umiddelbar to problemer som JIT compileren har som en klassisk ahead-of-time compiler ikke har

JIT-compilere har det med at være mange faktorer mere komplekse end traditionelle compilere. Det er ikke uvæsentligt i forbindelse med at vedligehold. Mit bud er at Java og C# har 10-20 gange så meget tid brugt på sig set i forhold til andre compilere, ikke mindst i forskningsforsøg også. Men det er også nødvendigt. Det kræver noget spidsfindighed at kunne erstatte et program med et andet mens det kører, og det skal kunne lade sig gøre begge veje: optimering såvel som deoptimering.

Pointen er at en relativt simpel compiler, med et par af de typiske optimeringer, nemt hamler op med halvavancerede JIT-compilere i eksekveringshastighed. Og for at presse styrken ved profile-guided optimization ud, så skal der relativt set meget arbejde til.

Dertil kommer at folk fokuserer for meget på programydelse. Hvis bare vi kan erstatte halvdelen af samtlige Python, Javascript, og PHP-programmer derude med eksempeltvist Go, så reducerer vi kraftigt det nuværende spild af energi. Og Go-compileren har ikke rigtigt nogen avancerede optimeringer i sig, bare god gammeldags pæn kode-emit, lidt peephole osv. Det er først for nylig at de har indført SSA-form. Der skal slet ikke så meget til, og ydelse i toppen af kagen er langt mindre væsentligt for størstedelen af alle programmer.

Michael Cederberg

I princippet ikke. Men den tid, en JIT compiler bruger på optimeringer, går ud over køretiden.

Hvis programmet kører i lang tid gør det ingenting at der bliver brugt en smule tid på realtime optimering hvis bare det ikke går ud over latency og throughput.. Latency vil selvfølgeligt blive ramt, men hvis det holdes inden for det umålelige er det sjældent et problem. Hvis det ikke kører i lang tid, så gør det (i de fleste tilfælde) ingen forskel om programmet kører hurtigt eller langsomt.

En offline compiler kan bruge meget mere tid på optimeringer end en gennemsnitstiden for en enkelt kørsel af programmet.

En JIT compiler kan bruge tid på den del af programmet der betyder noget. Tommelfingerreglen siger at det er 2% af programmet ...

Så det er ikke sådan, at en JIT compiler ikke kan lave globale transformationer m.m., men det vil normalt ikke være en fordel.

Hvis programmet kører i mange dage, så gør det ingen forskel om JIT'teren bruger tid på at lave globale transformationer for at optimere. Og disse kan blive bedre fordi beslutningen om hvordan der skal optimeres baseres på real-life viden og ikke statisk analyse eller en syntetisk kørsel på "test data". Men som beskrevet ovenfor at vil det nok kun ske på den lille del af programmet der rent faktisk er performance kritisk.

JIT-compilere har det med at være mange faktorer mere komplekse end traditionelle compilere. Det er ikke uvæsentligt i forbindelse med at vedligehold. Mit bud er at Java og C# har 10-20 gange så meget tid brugt på sig set i forhold til andre compilere, ikke mindst i forskningsforsøg også. Men det er også nødvendigt. Det kræver noget spidsfindighed at kunne erstatte et program med et andet mens det kører, og det skal kunne lade sig gøre begge veje: optimering såvel som deoptimering.

Du ganske ret i at JIT-compilere er mere komplekse. Men set i lyset af at der i dag kun er 2 JIT-compilere der har større udbredelse (CLR og Oracle JVM), så burde den investering sagtens kunne løftes. I øvrigt har ganske små virksomheder bygget ret avancerede JIT-compilere så investeringen kan sagtens løftes og kompleksiteten bliver ikke enorm.

Og husk nu på at den investering der er lavet ikke er for at lave det samme som traditionelle compilere laver. Det er for at lave noget der er bedre.

Dertil kommer at folk fokuserer for meget på programydelse. Hvis bare vi kan erstatte halvdelen af samtlige Python, Javascript, og PHP-programmer derude med eksempeltvist Go, så reducerer vi kraftigt det nuværende spild af energi.

Hvis det handler om at reducere det globale forbrug at energi, så ja. Men hvis det handler om at løse det problem jeg har foran mig, så nej. Hvis jeg fx skulle starte et projekt med at bygge en ny in-memory database, skal jeg så vælge JIT/non-JIT?

Indtil for nogle år siden kunne "traditionalisterne" sige at deres miljø var bedst til en masse opgaver (jeg var selv en af dem). Ligeså stille er den verden hvor C/C++ er bedst blevet mindre og mindre. I starten fordi de fleste problemer ikke kræver performance, men nu fordi JIT compilere nærmer sig samme performance som traditionelle compilere.

Isak Gjedbo

.. havde Luke Skywalker brugt en "Industrial Automaton R2-D280 GTX". Og det havde været Anakins 9. astromech droid siden han satte sig i fighteren på Naboo.
(Så blev Episode I aligevel godt for noget: metaforer :D)

Vi når vel ikke til et punkt hvor pålidelighed har prioritet blandt de store producenter lige foreløbligt. Det går direkte imod vores "Køb og smid væk" mentalitet, der absolut er den mest fordelagtige for profitmarginen.

De bruger stadig revolvere i Firefly, til trods for at de flyver rundt i hele solsystemet. Måske vi skulle være lidt mere Space Cowboys og lidt mindre Content Consumers, hvis trenden skal vendes.

Log ind eller Opret konto for at kommentere
Brugerundersøgelse Version2
maximize minimize