Hlavní navigace

RISCové mikroprocesory s komprimovanými instrukčními sadami (2)

22. 12. 2015
Doba čtení: 21 minut

Sdílet

 Autor: Derrick Coetzee, podle licence: Public Domain CC0
V předchozí části článku o mikroprocesorech s RISCovou architekturou jsme si uvedli důvody, které vedly návrháře RISCových procesorů k zavedení takzvaných „komprimovaných“ instrukcí. Kromě minule popsané sady MIPS16e samozřejmě existují i sady další, především pak RVC (RISC-V „C“).

Obsah

1. RISCové mikroprocesory s komprimovanými instrukčními sadami (2)

2. RVC (RISC-V – C)

3. Kódování instrukcí různé šířky v architektuře RISC-V

4. Kódování instrukcí při použití RVC

5. Formát instrukcí typu CL (LOAD)

6. Formát instrukcí typu CS (STORE)

7. Formát instrukcí typu CB (BRANCH)

8. Formát instrukcí typu CJ (JUMP)

9. Formát instrukcí typu CR (REGISTER)

10. Formát instrukcí typu CI (IMMEDIATE)

11. Formát instrukcí typu CCS (stack-relative store)

12. Formát instrukcí typu CIW (WIDE IMMEDIATE)

13. Výsledky měření: zmenšení velikosti kódu použitím RVC

14. Odkazy na Internetu

1. RISCové mikroprocesory s komprimovanými instrukčními sadami (2)

„The majority of today's processors can’t rightfully be called completely RISC or completely CISC. The two textbook architectures have evolved towards each other to such an extent that there’s no longer a clear distinction between their respective approaches to increasing performance and efficiency.“

V předchozí části seriálu o mikroprocesorech s architekturou RISC jsme si uvedli několik důvodů, proč se u některých RISCových architektur (většinou těch komerčně úspěšných, což pravděpodobně nebude úplná náhoda :-) kromě původní čistě RISCové instrukční sady zavedla i instrukční sada s „komprimovanými“ instrukcemi, což v kontextu klasických RISCových mikroprocesorů znamená instrukce s šířkou osmi, ovšem většinou šestnácti bitů (alternativně též kombinace 16bitových a 32bitových instrukcí). Tyto komprimované instrukční sady se zpočátku začaly uplatňovat především v těch oblastech, kde lze použít pouze cache o relativně malé kapacitě a kde je přístup do paměti instrukcí pomalý (to platí zejména pro embedded zařízení vybavená Flash ROM, přeneseně pak i pro mikrořadiče). Zajímavé však je, že dnes tyto instrukční sady našly své uplatnění i v dalších oblastech, například u tabletů atd. To souvisí mj. i s neustále se zvětšujícím rozdílem mezi rychlostí CPU a dobou přístupu do pamětí (tento rozdíl se vlastně ještě násobí s tím, jak roste počet procesorových jader).

První popsanou „komprimovanou“ instrukční sadou byla sada MIPS16e používaná u některých mikroprocesorů s architekturou MIPS. Dnes si přiblížíme zejména možnosti, které v této oblasti nabízí progresivní architektura RISC-V, jejíž možnosti se neustále rozvíjejí a především je navržena tak, aby se RISC-V mohla rozvíjet několika směry. Popisem architektury RISC-V z pohledu programátora jsme se již zabývali v předchozích částech tohoto seriálu [1] [2] [3] a [4]. Vysvětlili jsme si princip kódování instrukcí i způsob vytváření nových rozšiřujících instrukčních sad. Poměrně specifická je v tomto ohledu především instrukční sada označená písmenem „C“, která je též nazývána RVC (RISC-V Compressed). Specifičnost instrukční sady „C“ spočívá v tom, že se v ní pracuje s instrukcemi o šířce šestnácti bitů a nikoli 32 bitů; navíc se v instrukčních slovech aktivně používají i nejnižší dva bity kódu instrukce (ty mají pro 32bitové instrukce hodnotu 11).

Pro malé připomenutí: v rámci projektu RISC-V již bylo navrženo a implementováno větší množství vzájemně se doplňujících instrukčních sad, zejména pak:

Označení Význam
  Oficiální sady instrukcí
I aritmetické instrukce (32/64 bit), load/store, skoky, rozvětvení, speciální operace
M rozšíření o instrukce pro násobení a dělení
A atomické operace typu read-modify-write (využitelné zejména pro multicore)
F operace s hodnotami typu float/single (jednoduchá přesnost)
D operace s hodnotami typu double (dvojitá přesnost)
  Další rozšíření
Q operace s hodnotami typu quad (čtyřnásobná přesnost)
L decimální aritmetika
C komprimované instrukce (viz též navazující kapitoly)
B bitové operace
T podpora pro transakční paměť
P SIMD operace

2. RVC (RISC-V – C)

„Leveraging 25 years of hindsight, RISC-V was designed to support compressed instructions from the start, leaving enough opcode space for RVC and many other extensions“

Tvůrci formátu instrukcí pro mikroprocesory RISC-V nezapomněli ani na to, že se tato procesorová jádra budou s velkou pravděpodobností používat mj. i v embedded systémech, kde se z různých důvodů (již zmíněná pomalá paměť Flash, relativně malá kapacita instrukční cache apod.) preferuje mít možnost vytvářet kód s větší hustotou, a to i za cenu menší výkonnosti celého čipu. Pro tyto účely byla navržena prozatím neoficiální instrukční sada „C“ nazývaná též RVC (RISC-V Compressed) s instrukcemi o šířce 16 bitů a nikoli 32 bitů. Tato instrukční sada byla vytvořena s tím, že se bude jednat o doplněk ke stávajícím instrukčním sadám, nebude tedy nutné provádět přepínání mezi různými režimy činnosti (na rozdíl od Thumb atd.).

Designéři architektury RISC-V se tak poučili z některých problémů, které dříve doprovázely jejich konkurenty, a to jak ARM (nutnost explicitního přepínání mezi A32 a Thumb, opuštění této kombinace v AArch64) tak i x86_64 (komplikace mikroprocesoru s instrukční sadou s instrukcemi proměnné délky). Podle soudobých měření se zdá, že instrukční sada „C“ může přinést zmenšení strojového kódu o přibližně 25 až 30%, což dále vede ke snížení výpadků instrukční cache o 20 až 25% (zde je ovšem nutné podotknout, že do značné míry záleží na podpoře v překladačích a JIT, tato podpora stále není dokonalá, takže lze předpokládat další zlepšení).

Mimochodem, podobně jako je dnes většinou nemožné najít prakticky používaný mikroprocesor s čistým CISC designem či naopak čistý RISC procesor, je i problematika měření hustoty binárních aplikací poměrně komplikovaná a jako taková je možné i měření provést šikovně takovým způsobem, aby bylo možné prosazovat vlastní výrobek (mikroprocesor) na úkor konkurence. Pěkně je to vidět například na následujících dvou zprávách, které se bez dalších podrobností zmiňují o rozdílech mezi architekturami ARM a MIPS: [1] [2]. I z tohoto důvodu je nutné počkat na měření založeném na široké bázi projektů (například celé Linuxové distro) a porovnat vlastnosti RVC s Thumb, Thumb 2 či MIPS16e.

3. Kódování instrukcí různé šířky v architektuře RISC-V

„Size matters.“

Připomeňme si nejprve již zmíněný způsob kódování instrukcí v mikroprocesorových jádrech s architekturou RISC-V. Ten je navržen takovým způsobem, aby byla instrukční sada velmi snadno rozšiřitelná, a to i kdykoli v budoucnosti. V RISC-V se pro základní rozlišení mezi „komprimovanými“ šestnáctibitovými instrukcemi a instrukcemi větší šířky používají nejnižší dva bity instrukčního slova, které pro plnohodnotné RISCové 32bitové instrukce obsahují dvojici jedniček a pro komprimované instrukce 16bitové pak jednu z kombinací 00, 01, 10. Dekodér tedy může jen na základě hodnot těchto dvou bitů velmi snadno určit, jakým způsobem má instrukci zpracovat (RISC-V je little endian, což je zde poměrně důležité):

 15             0
+----------------+
|xxxxxxxxxxxxxxaa| aa != 11
+----------------+

Ve skutečnosti však jdou možnosti RISC-V ještě mnohem zajímavější (i když prozatím příliš nevyužívané), neboť z dalších bitů operačního kódu instrukce lze zjistit, zda má instrukce šířku 32bitů či zda je dokonce ještě širší. Používá se následující způsob kódování, který teoreticky umožňuje tvořit instrukce o šířce až 320bitů, což by pravděpodobně vedlo k monstróznímu čipu s architekturou VLIW (i když: těžko říct, možnosti překladačů jsou dnes dosti značné v porovnání s dobou, kdy VLIW začínalo). Nás bude samozřejmě zajímat především kódování 32bitových operačních kódů, které vypadá následovně:

 31            16 15             0
+----------------+----------------+
|xxxxxxxxxxxxxxxx|xxxxxxxxxxxbbb11| bb != 111
+----------------+----------------+

Pro (prozatím) teoretické instrukce o šířce 48 bitů, které dnes neexistují, se používá tento formát:

 47            32 31            16 15             0
+----------------+----------------+----------------+
|xxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxx|xxxxxxxxxx011111|
+----------------+----------------+----------------+

A konečně pro instrukce s operačním kódem dlouhým 64 bitů by se použil následující formát:

 63            48 47            32 31            16 15             0
+----------------+----------------+----------------+----------------+
|xxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxx|xxxxxxxxx0111111|
+----------------+----------------+----------------+----------------+

Poznámka: šířka operačních kódů instrukcí žádným způsobem neurčuje šířku operandů. To, že základní instrukční sada RISC-V, resp. přesněji řečeno RVI32, používá instrukce o šířce 32 bitů a operandy o šířce taktéž 32 bitů, je z tohoto pohledu vlastně „náhoda“. Ostatně vzpomeňme například na již zmíněnou architekturu A32 (ARM) s instrukční sadou Thumb (32bitové operandy, 16bitové instrukce) či A64 (AArch64) s 64bitovými operandy a 32bitovými instrukcemi.

4. Kódování instrukcí při použití RVC

Aby bylo možné zakódovat instrukce, které měly původně šířku 32 bitů do pouhých šestnácti bitů, museli tvůrci provést stejné změny v instrukční sadě, s jakými jsme se již setkali minule:

  • Zmenšit počet pracovních registrů použitelných u některých instrukcí (někdy se jedná pouze o osm registrů x8 až x15, jiné instrukce pracují se všemi 32 registry, tj. včetně nulového registru).
  • Zmenšit šířku konstant, některé konstanty jsou automaticky násobeny 4× či 8×.
  • Sjednotit jeden zdrojový registr s registrem cílovým (dvouadresový kód).
  • Některé instrukce bylo nutné vynechat (musí se tedy použít jejich „široká“ varianta).

Najdeme zde ovšem i poměrně důležitou změnu: v instrukční sadě jsou zahrnuty instrukce pro načtení a ukládání dat do registrů matematického koprocesoru. Tvůrci instrukční sady argumentují tím, že tyto instrukce jsou používány velmi často a proto si zaslouží být součástí komprimované instrukční sady. I zde bylo nutné snížit počet adresovatelných registrů, a to konkrétně na registry f8f15 (což koreluje s podmnožinou celočíselných registrů x8x15).

V rámci komprimované instrukční sady „C“ se používá celkem osm různých formátů instrukčních slov:

# Zkratka Význam Poznámka
1 CL instrukce typu LOAD lze použít osm pracovních registrů x8..x15
2 CS instrukce typu STORE lze použít osm pracovních registrů x8..x15
3 CB rozvětvení (BRANCH) lze použít osm pracovních registrů x8..x15
4 CJ skok (JUMP) nepoužívá se žádný registr, pouze adresa skoku
5 CR operace s registry (REGISTER) lze použít jakýkoli registr
6 CI operace s konstantou (IMMEDIATE) lze použít jakýkoli registr
7 CCS stack-relative store lze použít jakýkoli registr
8 CIW WIDE IMMEDIATE lze použít osm pracovních registrů x8..x15

Jednotlivé formáty instrukcí jsou podrobněji popsány v navazujících kapitolách.

5. Formát instrukcí typu CL (LOAD)

První formát instrukcí, s nímž se dnes setkáme, je formát používaný většinou základních instrukcí typu LOAD, tj. instrukcí, které slouží pro načtení operandu do vybraného pracovního registru. Instrukce používající formát CL mají instrukční slovo rozděleno na tato bitová pole:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|  imm   |   rs1  | imm |   rd   | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 imm offset rozdělený na dvě části
3 rs1 index registru, v němž je uložena bázová adresa, může se jednat o registr x8 až x15
4 rd index cílového registru, do něhož se uloží načtená data, registry x8 až x15 či f8 až f15
5 op obsahuje kód C0

Podporovány jsou tyto instrukce:

# Instrukce Popis
1 C.LW načtení 32bitového slova z adresy offset×4+rs1
2 C.LD načtení 64bitového slova z adresy offset×8+rs1
3 C.LQ načtení 128bitového slova z adresy offset×16+rs1
4 C.FLW načtení 32bitové hodnoty typu float z adresy offset×4+rs1
5 C.FLD načtení 64bitové hodnoty typu double z adresy offset×8+rs1

Na tomto místě je důležité si uvědomit, že pouze některé instrukce mohou být podporovány zvoleným čipem (což ostatně platí i pro dále popsané instrukce). Například jen čipy s matematickým koprocesorem podporují instrukce C.FLW a C.FLD, na čistě 32bitových čipech nebudou podporovány instrukce C.LD a C.LQ atd. Jediná univerzální instrukce je zde C.LW.

6. Formát instrukcí typu CS (STORE)

Opakem instrukcí typu LOAD jsou samozřejmě instrukce typu STORE sloužící pro uložení obsahu vybraného pracovního registru (či registru matematického koprocesoru) na zvolenou adresu operační paměti:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|  imm   |   rs1  | imm |   rs2  | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 imm offset rozdělený na dvě části
3 rs1 index registru, v němž je uložena bázová adresa, může se jednat o registr x8 až x15
4 rs2 index registru obsahujícího data, která se mají uložit, registry x8 až x15 či f8 až f15
5 op obsahuje kód C0

Podporovány jsou tyto instrukce:

# Instrukce Popis
1 C.SW uložení 32bitového slova na adresu offset×4+rs1
2 C.SD uložení 64bitového slova na adresu offset×8+rs1
3 C.SQ uložení 128bitového slova na adresu offset×16+rs1
4 C.FSW uložení 32bitové hodnoty typu float na adresu offset×4+rs1
5 C.FSD uložení 64bitové hodnoty typu double na adresu offset×8+rs1

Navíc sem spadají i aritmeticko-logické instrukce používající jen registry x8 až x15:

# Instrukce Popis
1 C.AND operace AND
2 C.OR operace OR
3 C.XOR operace XOR
4 C.SUB rozdíl
5 C.ADDW součet se znaménkovým rozšířením výsledku před zápisem
6 C.SUBW rozdíl se znaménkovým rozšířením výsledku před zápisem

7. Formát instrukcí typu CB (BRANCH)

Instrukce sloužící pro provedení podmíněného rozvětvení, tj. instrukce typu BRANCH, používají další specifický instrukční formát, který se odlišuje od již popsaných formátů:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function| offset |   rs1  |    offset    | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 offset offset rozdělený na dvě části
3 rs1 index registru, jehož hodnota je porovnána s nulou
4 op obsahuje kód C1

Tento formát je podporovaný dvěma instrukcemi:

# Instrukce Popis
1 C.BEQZ pokud je registr rs1 roven nule, provede se skok na adresu PC+offset (&plusm;256 bajtů)
2 C.BNEZ pokud není registr rs1 roven nule, provede se skok na adresu PC+offset (&plusm;256 bajtů)

Povšimněte si, že další skoky (či větvení) s podmínkou nejsou v instrukční sadě „C“ podporovány; navíc zde existuje omezení na skoky v relativním rozsahu &plusm;256 bajtů. Pokud je zapotřebí skočit dál, musí překladač sám použít buď dvojici C.J+BxxZ či se uchýlit k použití „plnohodnotné“ instrukce RV32I či RV64I.

Navíc se tento formát používá i u instrukcí pro posun doprava (tyto instrukce se již nikam jinam nevešly, proto je část operačního kódu uložena v prvním bitovém poli s offsetem):

# Instrukce Popis
1 C.SRLI bitový posun registru rd/rs1 doprava
2 C.SRAI aritmetický posun registru rd/rs1 doprava
3 C.ANDI bitový součin

8. Formát instrukcí typu CJ (JUMP)

Instrukce pro nepodmíněný skok používají odlišný formát, než tomu bylo u instrukcí typu BRANCH. Povšimněte si, že se zde již nepoužívá žádný index zdrojového registru:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|          adresa skoku          | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 adresa skoku (relativní v rozsahu &plusm;2kB)
3 op obsahuje kód C1

Tento formát je opět podporovaný pouze dvěma instrukcemi, a to konkrétně instrukcemi C.J a C.JAL:

# Instrukce Popis
1 C.J provede se skok na adresu PC+offset (&plusm;2kB)
2 C.JAL provede se skok na adresu PC+offset (&plusm;2kB) + uložení návratové adresy do registru x1

Instrukce C.JAL je zajímavá, protože implicitně adresuje registr x1 pro uložení návratové adresy. V případě, že se mají skoky provádět na libovolnou adresu, je nutné použít instrukce C.JR a C.JALR, které však využívají odlišný instrukční formát.

9. Formát instrukcí typu CR (REGISTER)

Tento formát je využíván mnoha instrukcemi, které potřebují adresovat dva zdrojové registry popř. jeden zdrojový registr a jeden registr cílový. Speciálním případem jsou instrukce skoku C.JR a C.JALR, u nichž se používá jen jediný zdrojový registr (druhý zdrojový registr je nulový):

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  function |    rd/rs1    |      rs2     |  op |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 rd/rs1 první zdrojový registr či cílový registr
3 rs2 druhý zdrojový registr či nula (u skoků)
4 op obsahuje kód C0 či C2

Tento formát používají instrukce provádějící různé operace, proto je tabulka složitější, než v předchozích kapitolách:

# Instrukce Popis
1 C.JR skok na adresu uloženou v registru rs1, rs2 musí být nulový
2 C.JALR podobně C.JR, jen navíc uloží návratovou hodnotu do registru x1
     
3 C.MV přesun dat mezi registry, kromě x0
4 C.ADD součet (kromě x0, což je logické)
     
5 C.EBREAK kódován jako C.ADD s x0,x0

Poznámky:

  1. Zdrojový registr může být jakýkoli, tj. x0 až x31.
  2. Cílový registr může být jakýkoli kromě nuly, tj. x1 až x31.
  3. U instrukcí skoků C.JR a C.JALR musí být index registru rs2 nulový, jinak by se změnil operační kód instrukce.

10. Formát instrukcí typu CI (IMMEDIATE)

Všechny instrukce, u nichž je zapotřebí použít jeden zdrojový nebo cílový registr a konstantu, používají formát CI:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|im|    rd/rs1    |      imm     | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 imm konstanta (má různý význam podle typu instrukce)
3 rd/rs1 index zdrojového nebo cílového registru
4 op obsahuje kód C1 nebo C2

Tento formát používají instrukce provádějící různé operace, proto je tabulka opět složitější, než v předchozích kapitolách:

# Instrukce Popis
1 C.LWSP načtení 32bitového slova z adresy x2+offset×4 s uložením výsledku do registru rd
2 C.LDSP načtení 64bitového slova z adresy x2+offset×8 s uložením výsledku do registru rd
3 C.LQSP načtení 128bitového slova z adresy x2+offset×16 s uložením výsledku do registru rd
4 C.FLWSP načtení 32bitového slova (float) z adresy x2+offset×4 s uložením výsledku do registru rd
5 C.FLDSP načtení 64bitového slova (double) z adresy x2+offset×8 s uložením výsledku do registru rd
     
6 C.LI znaménkové rozšíření šestibitové konstanty a uložení do registru rd
7 C.LUI bezznaménkové rozšíření šestibitové konstanty a uložení do registru rd na bity 12..17
     
8 C.ADDI přičtení konstanty (zdrojový registr=cílový registr)
9 C.ADDIW přičtení konstanty a rozšíření na 64bitů (zdrojový registr=cílový registr)
10 C.ADDI16SP podobné C.LUI, výsledek je x2, konstanta je však násobena 16ti
     
11 C.SLLI bitový posun registru rd/rs1 doleva
     
12 C.NOP rd/rs1=0, imm=0

Poznámky:

  1. U prvních tří instrukcí platí, že registr rd nesmí být x0 (to by změnilo operační kód instrukce, navíc nemá význam ukládat nic do registru s konstantní nulou).
  2. U instrukce C.LI nesmí být rd=x0
  3. U instrukce C.LUI nesmí být rd=x0 či x2
  4. Instrukce C.SLLI dokáže pracovat se všemi registry, ovšem instrukce pro posun doprava nikoli. Je tomu tak z toho důvodu, že posuny doleva jsou častější, proto dostaly v instrukčním souboru prioritu.

11. Formát instrukcí typu CCS (stack-relative store)

Tento instrukční formát je využit u specializovaných instrukcí, u nichž se pro určení bázové adresy implicitně používá registr x2. Pokud se tento registr využívá ve funkci ukazatele na vrchol zásobníkového rámce, mohou instrukce z této skupiny sloužit pro přístup k lokálním proměnným uloženým právě na zásobníkovém rámci:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|       offset       |      rs2     | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 offset konstanta použitá pro výpočet adresy na zásobníku
3 rs2 zdrojový registr (libovolný, včetně x0!)
4 op obsahuje kód C2

Tento formát může být podporovaný až pěti instrukcemi, v závislosti na schopnostech konkrétního čipu:

# Instrukce Popis
1 C.SWSP uložení obsahu registru rs2 (32bitového slova) na adresu x2+offset×4
2 C.SDSP uložení obsahu registru rs2 (64bitového slova) na adresu x2+offset×8
3 C.SQSP uložení obsahu registru rs2 (128bitového slova) na adresu x2+offset×16
4 C.FSWSP uložení obsahu FP registru rs2 (float) na adresu x2+offset×4
5 C.FSDSP uložení obsahu FP registru rs2 (double) na adresu x2+offset×8

12. Formát instrukcí typu CIW (WIDE IMMEDIATE)

Tento formát používá pouze jediná instrukce C.ADDI4SPN:

 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|function|         imm           |   rd   | op  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Význam jednotlivých bitových polí:

# Bitové pole Význam
1 function kód prováděné operace
2 imm konstanta
3 rd cílový registr
4 op obsahuje kód C0

Instrukce C.ADDI4SPN vypočte offset×4, přičte k němu obsah registru x2 a uloží výsledek do cílového registru.

13. Výsledky měření: zmenšení velikosti kódu použitím RVC

Podívejme se nyní na výsledky měření, konkrétně na to, jak se zmenšil 64bitový Linuxový kernel a které instrukce na zmenšení měly největší vliv (ve skutečnosti máme k dispozici více výsledků měření, ty se však týkaly především benchmarků, což není tak praktický příklad jako v případě kernelu):

Instrukce % zmenšení
C.MV 5,00 %
C.LDSP 4,44 %
C.SDSP 3,79 %
C.LI 2,86 %
C.LD 2,09 %
C.J 1,53 %
C.BEQZ 1,24 %
C.JR 1,05 %
C.ADDI 0,95 %
C.ADD 0,91 %
   
Celkově: 31,11 % (všechny instrukce)

Osobně mi tyto výsledky přijdou být velmi zajímavé, protože se ukazuje, že ve statickém kódu se nejčastěji vyskytují instrukce pro přenosy dat (prvních pět řádků), teprve poté podmíněné a nepodmíněné skoky a v první desítce nalezneme pouze dvě ALU instrukce, a to sčítání!

root_podpora

Ovšem dynamické měření (tj. počet provedených) instrukcí nám dá zcela odlišné výsledky:

Instrukce % zmenšení
C.BNEZ 3,62 %
C.LD 3,29 %
C.LI 2,73 %
C.ADD 1,84 %
C.MV 1,37 %
C.J 1,35 %
C.LDSP 1,31 %
C.ADDI 1,26 %
C.SDSP 1,18 %
C.SD 1,13 %
   
Celkově: 26,11 % (všechny instrukce)

Asi podle očekávání toto měření „vyhrála“ instrukce pro podmíněný skok, která je (logicky) součástí většiny smyček.

14. Odkazy na Internetu

  1. RISC-V Draft Sompressed ISA Version 1.9 Released
    https://blog.riscv.org/2015/11/risc-v-draft-compressed-isa-version-1–9-released/
  2. RISC vs. CISC: the Post-RISC Era
    http://archive.arstechnica­.com/cpu/4q99/risc-cisc/rvc-1.html
  3. Introduction to ARM Thumb
    http://www.embedded.com/electronics-blogs/beginner-s-corner/4024632/Introduction-to-ARM-thumb
  4. Code Size – a comprehensive comparison of microMIPS32 and Thumb code size using many Megabytes of customer code
    https://community.arm.com/grou­ps/processors/blog/2014/04/28/co­de-size-a-comprehensive-comparison-of-micromips32-and-thumb-code-size-using-many-megabytes-of-customer-code
  5. MIPS MCUs Outrun ARM
    http://www.linleygroup.com/new­sletters/newsletter_detail­.php?num=5117
  6. Improving Energy Efficiency and Reducing Code Size with RISC-V Compressed
    http://www.eecs.berkeley.e­du/~waterman/papers/ms-thesis.pdf
  7. An Introduction to Lock-Free Programming
    http://preshing.com/20120612/an-introduction-to-lock-free-programming/
  8. Sequential consistency
    https://en.wikipedia.org/wi­ki/Sequential_consistency
  9. Understanding Atomic Operations
    https://jfdube.wordpress.com/2011/11/30/un­derstanding-atomic-operations/
  10. Load-link/store-conditional
    https://en.wikipedia.org/wiki/Load-link/store-conditional
  11. The RISC-V Compressed Instruction Set Manual (Pozor: verze 1.7)
    http://riscv.org/spec/riscv-compressed-spec-v1.7.pdf
  12. Carry bits, The Architect's Trap
    http://yarchive.net/comp/ca­rry_bit.html
  13. Microprocessor Design/ALU Flags
    https://en.wikibooks.org/wi­ki/Microprocessor_Design/A­LU_Flags
  14. Flags register in an out-of-order processor
    http://cs.stackexchange.com/qu­estions/42095/flags-register-in-an-out-of-order-processor
  15. AMD Am29000
    https://en.wikipedia.org/wi­ki/AMD_Am29000
  16. Status register
    https://en.wikipedia.org/wi­ki/Status_register
  17. AMD Am29000 microprocessor family
    http://www.cpu-world.com/CPUs/29000/
  18. AMD 29k (Streamlined Instruction Processor) ID Guide
    http://www.cpushack.com/Am29k.html
  19. AMD Am29000 (Wikipedia)
    http://en.wikipedia.org/wi­ki/AMD_Am29000
  20. AMD K5 („K5“ / „5k86“)
    http://www.pcguide.com/ref/cpu/fam/g5K5-c.html
  21. Comparing four 32-bit soft processor cores
    http://www.eetimes.com/au­thor.asp?section_id=14&doc_id=1286116
  22. RISC-V Instruction Set
    http://riscv.org/download­.html#spec_compressed_isa
  23. RISC-V Spike (ISA Simulator)
    http://riscv.org/download.html#isa-sim
  24. RISC-V (Wikipedia)
    https://en.wikipedia.org/wiki/RISC-V
  25. David Patterson (Wikipedia)
    https://en.wikipedia.org/wi­ki/David_Patterson_(compu­ter_scientist)
  26. OpenRISC (oficiální stránky tohoto projektu)
    http://openrisc.io/
  27. OpenRISC architecture
    http://openrisc.io/architecture.html
  28. Emulátor OpenRISC CPU v JavaScriptu
    http://s-macke.github.io/jor1k/demos/main.html
  29. OpenRISC (Wikipedia)
    https://en.wikipedia.org/wi­ki/OpenRISC
  30. OpenRISC – instrukce
    http://sourceware.org/cgen/gen-doc/openrisc-insn.html
  31. OpenRISC – slajdy z přednášky o tomto projektu
    https://iis.ee.ethz.ch/~gmichi/a­socd/lecturenotes/Lecture6­.pdf
  32. Maska mikroprocesoru RISC 1
    http://www.cs.berkeley.edu/~pat­trsn/Arch/RISC1.jpg
  33. Maska mikroprocesoru RISC 2
    http://www.cs.berkeley.edu/~pat­trsn/Arch/RISC2.jpg
  34. C.E. Sequin and D.A.Patterson: Design and Implementation of RISC I
    http://www.eecs.berkeley.e­du/Pubs/TechRpts/1982/CSD-82–106.pdf
  35. Berkeley RISC
    http://en.wikipedia.org/wi­ki/Berkeley_RISC
  36. Great moments in microprocessor history
    http://www.ibm.com/develo­perworks/library/pa-microhist.html
  37. Microprogram-Based Processors
    http://research.microsoft.com/en-us/um/people/gbell/Computer_Struc­tures_Principles_and_Exam­ples/csp0167.htm
  38. Great Microprocessors of the Past and Present
    http://www.cpushack.com/CPU/cpu1.html
  39. A Brief History of Microprogramming
    http://www.cs.clemson.edu/~mar­k/uprog.html
  40. What is RISC?
    http://www-cs-faculty.stanford.edu/~ero­berts/courses/soco/projec­ts/2000–01/risc/whatis/
  41. RISC vs. CISC
    http://www-cs-faculty.stanford.edu/~ero­berts/courses/soco/projec­ts/2000–01/risc/risccisc/
  42. RISC and CISC definitions:
    http://www.cpushack.com/CPU/cpu­AppendA.html
  43. FPGA
    https://cs.wikipedia.org/wi­ki/Programovateln%C3%A9_hra­dlov%C3%A9_pole
  44. The Evolution of RISC
    http://www.ibm.com/develo­perworks/library/pa-microhist.html#sidebar1
  45. SPARC Processor Family Photo
    http://thenetworkisthecom­puter.com/site/?p=243
  46. SPARC: Decades of Continuous Technical Innovation
    http://blogs.oracle.com/on­therecord/entry/sparc_deca­des_of_continuous_technical
  47. The SPARC processors
    http://www.top500.org/2007_o­verview_recent_supercompu­ters/sparc_processors
  48. Reduced instruction set computing (Wikipedia)
    http://en.wikipedia.org/wi­ki/Reduced_instruction_set_com­puter
  49. MIPS architecture (Wikipedia)
    http://en.wikipedia.org/wi­ki/MIPS_architecture
  50. Very long instruction word (Wikipedia)
    http://en.wikipedia.org/wi­ki/Very_long_instruction_word
  51. Classic RISC pipeline (Wikipedia)
    http://en.wikipedia.org/wi­ki/Classic_RISC_pipeline
  52. R2000 Microprocessor (Wikipedia)
    http://en.wikipedia.org/wi­ki/R2000_(microprocessor)
  53. R3000 Microprocessor (Wikipedia)
    http://en.wikipedia.org/wiki/R3000
  54. R4400 Microprocessor (Wikipedia)
    http://en.wikipedia.org/wiki/R4400
  55. R8000 Microprocessor (Wikipedia)
    http://en.wikipedia.org/wiki/R8000
  56. R10000 Microprocessor (Wikipedia)
    http://en.wikipedia.org/wiki/R10000
  57. SPARC (Wikipedia)
    http://en.wikipedia.org/wiki/Sparc
  58. CPU design (Wikipedia)
    http://en.wikipedia.org/wi­ki/CPU_design
  59. Control unit (Wikipedia)
    http://en.wikipedia.org/wi­ki/Control_unit

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.