CPU popularitetens forbandelse

I dag fylder IBM's S/360 mainframe 50 år.

S/360 var den første CPU der blev ramt af popularitetens forbandelse.

Kort og godt går forbandelsen ud på at der kommer folk og kaste penge på bordet og siger "Kan I ikke tilføje en instruktion der ..."

Mit yndlingseksempel er "MVCOS" instruktionen -- "Move-with-Optional-Specifications-Facility"

Nogen der tør gætte på hvad den gør ?

Hjælper det hvis jeg siger at den kan gøre alt hvad MVCP, MVCS, MVCDK, MVCSK og MVCK kan gøre, men op til 16 gange bedre ?

Eller, at instruktionen er "Available to problem-state code (subject to PSW key mask)" ?

Jeg kan også nævne at instruktionen er patenteret i US PAT 7,594,094 ?

Slet ingen der tør byde ind med et gæt ?

OK, den er også svær:

Det er en instruktion der kan flytte data fra et sted til et andet i maskinen.

Og ja, det kan man åbenbart få patent på i USA.

En meget god selskabsleg blandt IT nørder, er "Gæt en Mainframe Instruktion", download IBM's handy z/Architecture Reference Summary og aftenen bliver helt sikkert munter ud over alle grænser.

Forbandelsen har ud over perler som MVCOS givet en z/Series maskine (mindst!) 64 forskellige instruktioner for addition, hvoraf alle på nær to beskrives startende med "Add", mens de sidste to er all-caps: "ADD".

Når jeg skriver "mindst" er det fordi der naturligvis findes "optioner" for instruktionssæt, for kunder med særlige behov og, oftest, særlige evner til at betale ud af statskassen.

Den næste CPU der blev ramt af denne særlige forbandelse var PC'ens x86 arkitektur, der nu om dage kan præstere instruktioner som "MASKMOVDQU" -- "Masked Move of Double Quadword Unaligned"

Galimatias er ikke nået helt samme niveau som IBM's mainframes endnu, men x86 er også kun 36 år gammel, i den alder havde IBMs mainframes stadig mange nye spændende instruktioner forude.

Og seneste offer er min ellers højt elskede ARM cpu, der blev født med et elegant RISC design.

For at mindske instruktionsbåndbredden fik en 16-bit "lite" variant af instruktionssættet kaldet "thumb" som banede vejen for anvendelse i embedded verdenen.

Success som CPU ? "dam-daaah-daAM!" folk begynder at sige "Hvis bare der var en instruktion som ... så ville vi købe en million."

"Thumb-2" instruktionssættet er ikke gået helt bananas, men hvis man kigger på hvorledes de er proppet ind i alle mulige underlige hjørner er det helt klart hvor desparat et projekt der er tale om. Prøv at skrive en disassmbler hvis I ikke tror mig.

Og ARM er en årsunge på sølle 29 år, i den alder var IBM's s/390 først lige begyndt at lære IEEE floating point, tænk bare hvad ARM kan drive det til i de næste 21 år.

I Firserne og Halvfemserne blev de respektive meritter i RISC og CISC diskuteret op og ned af alle former for elfenbenstårne, ofte med dataloger på "RISC er bevisligt bedre" og folk der fik løn for at skrive programmer på "Det kan godt være, men jeg skal fandme bruge en instruktion der ..." siden.

Historien har vist at det var rent spild af tid: Alle CPU'er med succes bliver CISC over tid.

phk

Kommentarer (15)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Casper Bang

Historien har vist at det var rent spild af tid: Alle CPU'er med succes bliver CISC over tid.

Det handler vel et-eller-andet-sted bare om abstraktioner, på samme måde som vi ser det højere oppe i stakken?! Du er jo velkommen til at rulle dine egne vtables i C hvis du ønsker polymorfisme, men de fleste vælger så alligevel at omfavne C++. Endnu højere oppe, istedet for at rode med din egen reference-counting mekanisme i C++, benyt istedet et managed sprog med en GC.

Abstraktioner er vel vores primære våben imod kompleksitet?

  • 1
  • 0
Poul-Henning Kamp Blogger

Abstraktioner er vel vores primære våben imod kompleksitet?

Men disse stadigt mere specialiserede instruktioner er netop ikke et forsøg på abstraktion, nærmest det modsatte: Det er forsøg på at gøre underlige, men for nogle kunder vigtige, specialtilfælde en lille bitte smule hurtigere, på bekostning af instruktionsættets ortogonalitet og arkitektur.

  • 5
  • 0
Troels Henriksen

Historien har vist at det var rent spild af tid: Alle CPU'er med succes bliver CISC over tid.

Ah, ja i hvert fald udadtil, men indeni er moderne x86-processorer jo baseret på et enklere RISC-instruktionssæt, som de eksterne misfostre af CISC-instruktioner oversættes til.

Abstraktioner er vel vores primære våben imod kompleksitet?

Har du kigget på den instruktionsmanual PHK linker til? Der er ingen abstraktion over en variation af en ADD-instruktion der også liiiiige tillader at konvertere fra 32-bit til 64-bit heltal, mens man er i gang.

  • 1
  • 0
Casper Bang

Har du kigget på den instruktionsmanual PHK linker til?

Nej det må jeg jo indrømme, jeg tænkte bare lidt over hvad jeg opfattede som RISC melankoli - men jeg medgiver at de oplyste eksempler ikke virker til at kaste positivt lys over CISC. :)

Nu kan omfanget af "Complete" i CISC jo så variere en del. Netop for ARM/SoC verdenen, kan vi vel ikke gå ret mange andre veje. Min første Android enhed emulerede FPU'en (Qualcomm MSM7201) og jeg ville da nok savne NEON/SIMD hvis de ikke var i min seneste enhed (Qualcomm MSM8974AC).

Derfor, hvis der er plads på dien, kunne jeg såmænd også godt forestille mig en fremtid hvor support for base-10 instruktioner blev ganske normalt, men her afslører jeg nok bare, at jeg ofte befinder mig på applikationslaget hvor IEEE-754 repræsentation og afrunding er til besvær.

  • 0
  • 0
Poul-Henning Kamp Blogger

Nej det må jeg jo indrømme, jeg tænkte bare lidt over hvad jeg opfattede som RISC melankoli - men jeg medgiver at de oplyste eksempler ikke virker til at kaste positivt lys over CISC. :)

Mnjae, det er så den anden side.

Idag er instruktionstrømmen jo bare en codning af intention, det er ikke noget der styrer elektronikke direkte på high-end CPU. Som Troels er inde på bliver instruktionsstrømmen oversat til en intern instuktionsstrøm, via noget der begynder at ligne en compilers optimeringstrin, inden der faktisk sker noget.

Derfor er CISC ikke per definition ringere.

I sidste ende handler det om hvor mange bytes/sec instruktionsstrøm der skal til at udtrykke din intention og om dette tal udgør en performance-begrænsende faktor i forhold til resten af det arbejde der skal gøres.

Omvendt har selv de mest RISC'ed arkitekturer nogle CISC primitiver, fordi det stort set er den eneste måde at få et multi-CPU system synkroniseret effektivt på.

  • 0
  • 0
Casper Bang

I sidste ende handler det om hvor mange bytes/sec instruktionsstrøm der skal til at udtrykke din intention og om dette tal udgør en performance-begrænsende faktor i forhold til resten af det arbejde der skal gøres.

Så nærmer vi os vel stille og roligt Shannon og en snak om teoretisk informationslærdom?!

Forskellen er måske at producer-consumer timing spiller ind også. Hvilket minder mig om en CISC-RISC software parallel der er at finde i hhv. JVM'en og CLR'en.

Gosling designede (den stak baserede) Java byte kode tilbage i de dage hvor instruktionerne skulle fortolkes én af gangen, hvorfor han derfor valgte at kæde operator og operant-type sammen. Fordelen var, at fortolkeren nu hurtigere kunne afgøre type-information ud fra selve instruktionen, men ulempen var så at add, sub, mul, div, rem og neg skulle overloades for hhv. int, long, float og double - ialt altså 24 instruktioner.

Hejlsberg valgte at IL koden for CLR'en aldrig skulle fortolkes men altid JIT kompileres, og at type-informationen derfor alligevel var udledt. Dette resulterede i et noget simplere IL design med blot 6 instruktioner.

Og hvad er så bedst? Tja, det kommer jo så an på om man vil have kompleksiteten på producer- eller consumer-siden. Sun endte dog med at løbe panden mod en mur, da der ikke var flere frie byte-koder tilbage.

  • 0
  • 0
Torben Mogensen Blogger

Der er ganske rigtigt blevet tilføjet mange underlige ting til ARM gennem tiderne. Det startede i det små: Mellem ARM2 og ARM3 (ARM1 var stort set kun en prototype) blev der kun tilføjet en SWAP instruktion, der blev brugt til multiprogrammering. Men efter ARM blev udskilt som separat firma, gik det hurtigt: ARM6 (man sprang 4 og 5 over) havde taget statusflagene ud af PC-registret til et separat register, men beholdt bagudkompatibilitetsmodes, som bevarede den gamle model med statusflag i PC. Ved ARM8 (såvidt jeg husker) blev der tilføjet 16-bit load/store (oprindeligt var der kun 8- eller 32-bit load/store), og nogenlunde samtidigt kom Thumb, som efter min mening ikke var en specielt elegant måde at få 16-bit indkodning af instruktioner (Sofie Wilson havde foreslået, at man brugte instruktioner med "NV" (never) betingelseskode til at indkode to ubetingede 14-bit instruktioner, så man kunne blande korte og lange instruktioner mere frit end Thumb -- dog med den begrænsning, at de korte instruktioner kom i par). Thumb blev dog senere erstattet af Thumb2, som tillod 16-bit og 32-bit indkodninger samtidigt, men, som PHK siger, var indkodningen ikke specielt elegant, da man ville beholde indkodningen af 16-bit instruktionerne fra Thumb uændret, og derfor måtte proppe de lange instruktioner ind i de irregulære huller i indkodningen af Thumb. Dertil kom, at der blev lavet ARM-varianter, der kunne udføre en delmængde af JVM natively.

Heldigvis ser 64-bit instruktionssættet fornuftigt ud: Man har lavet en helt ny indkodning, og lavet instruktionssættet endnu mere RISC end det oprindelige ARM2 instruktionssæt. Faktisk ligner det mere MIPS end ARM2. Men der kommer helt sikkert tilføjelser til senere.

  • 1
  • 0
Thomas Graversen

RISC filosofien er ikke at reducere antallet af implementerede instruktioner i CPU'en, men at udføre de mest benyttede instruktioner hurtigst muligt.
R'et i RISC betyder IKKE at der skal være et lille antal instruktioner i CPU'en. Men at hver instruktion udfører en Reduceret funktionalitet (ift. CISC).

En karakteristik ting for RISC er at den foretager sine operationer på registre. For at udføre instruktioner hurtigst muligt i RISC, blev man nød til at kassere 'load_from_memory -> operationX -> store_to_memory' type instruktioner. Ved at dele operationen op i 3 RISC instruktioner kan man bedre afkoble langsomme memory cycles fra operationer. Det reducerer antallet af adresserings modes for de fleste instruktioner (simplere at lave orthogonal instruktions sæt).
Der er i princippet ikke noget der hindrer at en RISC har flere instruktioner i instruktions sættet end en CISC (bortset fra at loading af instruktionen kun må tage 1 cycle).

Se: http://en.wikipedia.org/wiki/Reduced_instruction_set_computing

  • 0
  • 0
Thomas Graversen

>>>Jo det er også netop derfor der er brug for CISC instruction for at kunne multiprogrammere. F.eks. atomisk læs og skriv, og ikke mindst læs, gør noget og skriv.

Jeg giver dig ret, at det er en CISC agtig instruktion.
jeg anfægter bare definitionen af hvad en RISC og CISC CPU er.
Det udelukker jo ikke at det stadig er en RISC CPU, at den har read-modify-write primitiver.

Grænsen mellem CISC og RISC er blevet gradvis udvisket. RISC og CISC låner fra hinanden. RISC operationer må gerne tage flere clockcycles. Det er karakteristisk at en RISC opererer på registre og at en CISC kan operere direkte i memory.

Jeg er bare ikke enig med PHK udsagn: "Historien har vist at det var rent spild af tid: Alle CPU'er med succes bliver CISC over tid."
Det er lidt for sort/hvid

For eksempel:
-Hvis en RISC cpu har lidt microcode, gør det den ikke til en CISC. (R'er i RISC står for Reduced)
-Hvis en CISC kan udføre en enkelt instruktion på 1 clockcycle, gør den heller ikke hele CPU'en til en RISC.
- En x86 er stadig en CISC (selvom den indeholder en RISC cpu backend).
- ARM en en RISC selvom den indeholder opcodes som er CISC agtige. De er begrænset til få områder.

Det er ikke antallet af instruktioner i CPU instruktionsætet, som afgør det, men kompleksiteten af hver instruktion.

ARM lavede Thumb mode for at forbedre code density (for at nærme sig CISC code density). Det giver bedre cache hit-ratio.

  • 0
  • 0
Torben Mogensen Blogger

At tælle antallet af forskellige instruktioner i et instruktionssæt er som at sælge elastik i metermål, for der er mange forskellige måder at tælle på. I nogle optællinger tæller man f.eks. addition med eller uden mente som to forskellige instruktioner, og i andre som en instruktion med et bit, der angiver om menten medtages. Tilsvarende for forskellige adresseringsformer ved lagertilgang, betingede eller ubetingede hop, lagertilgang med 8- 16 eller 32-bit af gangen, osv. Og hvis en opcode ændrer opførslen af den efterfølgende opcode, er det så en ekstra instruktion eller en ekstra instruktion for hver af de efterfølgende opcodes?

Groft sagt giver det ikke nogen mening at tælle instruktioner: Man kan altid lave sit mål, så det passer til den konklusion, man ønsker at få.

Der er heller ikke nogen generelt accepteret definition af RISC. Man ser i reglen på en checkliste, og hvis der er nok matches, så kalder man det RISC. Denne checkliste indeholder typisk blandt andet følgende elementer:

  • Hvor mange forskellige størrelser er der på instruktioner?
  • Hvor mange registre har specialfunktioner (dvs, at bestemte instruktioner implicit bruger dette register)?
  • Hvor mange opslag i TLB kan en instruktion maksimalt lave?
  • Hvor mange sekventielle afhængigheder kan der være i en enkelt instruktion?

hvor små tal indikerer RISC og større tal CISC. Men diskussionen er lidt irrelevant nu om dage: Den overvejende del af implementeringskompleksiteten er stort set uafhængig af instruktionssættet og vedrører i stedet mikroparallelitet og spekulativ udførsel. Da pipelining var det mest avancerede, man lavede i mikroprocessorer, da kunne CISC give en betragtelig besparelse, men det er ikke længere afgørende.

  • 0
  • 0
Frithiof Andreas Jensen

Så vidt jeg husker så kan man også microprogrammere S/360. Det var noget med at skrive specielle data til negative indexes på Fortran Arrays placeret strategisk i memory; Med micro-programmering kan hackeren definere sine egne instruktioner- eller om-definere de eksisterende "on-the-fly".

Jeg har hört om folk der syntes at ALU'en skulle bruge 200 betydende cifre og BCD for at ramme Moskva ordentligt.

  • 0
  • 0
Troels Henriksen

Det er også vigtigt at huske, at flere instruktioner ikke nødvendigvis er en dårlig ting. Ovenfor blev specielle instruktioner til synkronisering af parallelisme nævnt, men der kan også være ydelsesfordele ved f.eks. vektoriserede SIMD-instruktioner. En stor del af væksten i antallet af instruktioner på x86 skyldes netop disse, og de har en reel ydelsesfordel.

De eneste instruktioner man kan kalde "overflødige", er nok dem der er til for at gøre assemblerprogrammørens liv nemmere, men det er også mit indtryk at moderne arkitekturer sjældent bekymrer sig så meget om ham.

  • 0
  • 0
Log ind eller Opret konto for at kommentere