Dette indlæg er alene udtryk for skribentens egen holdning.

RISC vs. CISC vs. GZIP

70 kommentarer.  Hop til debatten
Blogindlæg20. marts 2011 kl. 21:34
errorÆldre end 30 dage

Nogle af os er gamle nok til at huske den religiøse RISC vs CISC krig der kørte i halvfemserne.

Idag er det ikke noget man tænker meget på, med mindre man faktisk sidder med næsen i noget maskinkode.

Jeg sidder og roder med at skrive en disassembler i Python til x86 arkitekturen (til mit lille PyRevEng) projekt og det giver stof til eftertanke i den retning.

Både IBM's mainframe instruktionssæt og Intels x86 familie, ser ud til at have fået hjulet i den samme fure: Hver gang man får en ny ide starter jagten på et hul i instruktionssættet hvor man kan klistre den ny feature på.

Artiklen fortsætter efter annoncen

Resultatet er at en instruktion på x86 idag kan være op til 15 bytes lang:

Et antal "legacy prefix" (CS:, DS:, ES:, SS:, LOCK: REP: osv)
Et REX prefix, der i 64 bit mode giver dobbelt så mange registre.
En Instruktionskode på 1 eller 2 bytes
En byte der specificere address-mode
En byte der skruer løvefødder og gesvejsninger på address-mode
Et offset til address-mode (1, 2 eller 4 bytes)
Et konstant (1, 2 eller 4 bytes)

Hertil kommer så de fem forskellige interne modes CPUen kan befinde sig i, inklusve disses sub-modes: (Real, v86, protected(16|32), long compat(16|32) og "rigtig long" der er en 32 bit mode med 64bit tilvalg gennem prefix bytes. Hertil VM, SMM og andre obscure supervisor modes) og endelig diverse extensions med obskure navne som "3DNow!" og "Screaming Sindie" og den slags.

Vi er kommet langt fra den første RISC computer, der kun havde 18 instruktioner: JMP, JSR, ISZ, DSZ, LDA, STA, ADD, SUB, NEG, ADC, MOV, INC, COM, AND, DIx, DOx, NIO og SKP.

Artiklen fortsætter efter annoncen

Men dengang var hardware dyr og derfor var det smart at bits i instruktionerne kunne hive direkte i hardware signaler uden for mange dikkedarer.

Når man bruger milliarder af transistorer på at bygge en CPU, er det sådan set lige meget og man bør ikke længere opfatte instruktionssættet som noget der har noget med hardware at gøre overhovedet, men derimod som en kommunikationsprotokol.

Den lunte fangede AMD med Athlon, som i virkeligheden består af en RISC-CPU med frontend-logik der oversætter X86 instruktioner til "rigtige" instruktioner.

ARM har også lavet et lidt tilsvarende trick med deres "thumb" instruktionssæt, der er en light-variant af de normale ARM instruktioner, smallere felter hist og her, som derfor fylder mindre plads.

I det lys giver et CISC instruktionssæt muligvis god mening, forudsat man designer det som en Huffman kode, så de mest brugte instruktioner er de korteste kodeord og sjældnt brugte eller meget langsomme instruktioner har lange kodeord.

Og når vi så har sagt det, er der jo nærliggende faktisk at gøre det til en Huffmankodning...

Al maskinkode, hvad enten man skriver det i hånden eller en kompiler spytter det ud, består af grupper af instruktioner adskilt af jumps, subroutinekald og andre afbrydelser.

Når den nu er igang med at tygge på mit program kunne en compiler ligeså godt komprimere disse "basic-blocks" med en huffman kode, eller for den sags skyld med gzip og CPU'en kunne så gunzip'e instruktionerne som en del af afkodningen.

Hvis komprimeringen ellers gør sit arbejde, sparer vi CPU-RAM båndbredde, hvilket stort set er den dyreste resource der findes i en computer idag.

Er der nogen der mangler en projektopgave ?

phk

70 kommentarer.  Hop til debatten
Debatten
Log ind for at deltage i debatten.
settingsDebatindstillinger
1
21. marts 2011 kl. 09:36

Spændende læsning! Jeg er ikke den store hardware/assembler haj, men komprimeringen du forslår ville så være en helt ny måde at kommunikere mellem maskininstruktioner i RAM og eksekveringen i CPU'en?

Altså skal der bygges (endnu) en oversætter oven på CPU'en hvis den ikke er specialbygget til natively at forstå zip'ede instruktioner.

Desuden skulle der også et ekstra led på compileren der skulle zippe maskininstruktionerne.

Det sværeste bliver nok at overtale mainstream hardware producenter til at implementere denne nye oversætter i deres CPU'er. Men du har ret, som projektopgave er det en spændende ide.

PS. (Med risiko for at lyde dum) Tillader almindelige forbruger-OS'er som Linux og Windows at man sender de instruktioner til CPU'en som man har lyst til, uanset om de er "lovlige" eller ej?

2
21. marts 2011 kl. 10:06

Nej, CPU'en sladrer til operativsystemet hvis et program forsøger at afvikle instruktioner der er ugyldige, eller som kræver flere rettigheder (på CPU-niveau) end den nuværende kontekst besider.

4
21. marts 2011 kl. 11:49

Antallet af transistorer brugt på rent faktisk at decode/udføre en instruktion er meget lille i forhold til de milliarder af transistorer der findes i de store CPUer. Så lidt ekstra Huffmandekodning på instruktionsbasis vil ikke betyde noget. Hvilket er hvad der i princippet er udnyttet i ARMs Thumb og MIPS' MIPS16 (og det selv om ingen af deres processorer er i nærheden at milliarder af transistorer, tælles mere i få millioner).

Det bliver lidt mere problematisk hvis man begynder at Zippe større blokke. Man risikere hurtigt at overheaded bliver større end det du spare. Hver kode-blok (kode mellem jumps) er ca 6 instruktioner (hvad jeg har fået fortalt af en compiler ekspert). Så der skal ikke meget til før man har hentet instruktioner ind i CPUen, for at kunne dekode en større blok instruktioner, der aldrig blive udført. En cache linie (16-64 bytes) er nok den største blok man vil kunne zippe som en blok. Og så lille en blok er det nok begrænset hvad den kan komprimeres. Så vil et dedikeret instruktionssæt, som f.eks dem ovenfor nævnt, nok være meget mere velegnet.

Men et andet sted man kunne spare en masse båndbredde er hvis man zippede data. F.eks er det jo velkendt at det meste data jo består af nuller. Og de kan som bekendt pakkes ret grundigt. Så selv en enkelt cache linie kan ofte komprimeres rigtig meget.