Praktiska kommentarer TSEA8 Datorteknik Y (och U) Föreläsning Kent Palmkvist, ISY Dagens föreläsning RISC Mer information om hur arkitekturen fungerar Begränsningar Lab extra tillfälle för redovisning Tisdag / kl. (i southfork) Extra presentationstillfällen Lab - Tisdag / 0- i Bussen Lab Tisdag / kl - Lab Onsdag / kl - Tävlingsresultat 9 olika kodbidrag ( från person) fungerade inte för alla testfall ollställning, start, timeout efter 0000 klockcykler Datakonflikter Bästa resultat:. klockcykler Styrkonflikter äst bästa resultat: klockcykler Branch prediction Tredje bästa resultat: 98 klockcykler Resterande resultat: 8., 0., 9., 9 Mitt eget försök (ren mikrokod): 88
Gustaf Colliander klockcykler Enkel RISC-baserad struktur, repetition Årets vinnare av ballerinapaket Enkelt exempel från kursboken (avsnitt.) RISC-arkitektur av LOAD-STORE typ Endast läsning/skrivning med instruktion (LOAD respektive STORE) Övriga instruktion sker endast med register i registerfil äst bästa var Erik Ahlrot på klockcykler (bara.% längre tid!) TSEA8 Datorteknik Y (och U), föreläsning, Kent Palmkvist Tips för Lab Uppgift : Ta reda på datacachens associativitet Pga utskrift kan ibland en extra cachemiss inträffa Om data inte får plats i cache fås många (>) extra cachemissar! Enkel RISC-baserad struktur, repetition, forts. Ingen mikrokod Maskininstruktionens bitar styr enheterna direkt (Write_Destination, ALU Function etc.) -bitar instruktion ( byte) => öka PC med vid varje instruktion Uppgift : Ta bort alla triggning av chipscope när ni ska kolla om koden går fort nog Varje koll av x och y koordinat samt anrop till trigger_logic_analyzer tar extra tid
Exekveringstid i exemplet Instruktion LDR D,(S,#L) ; opcode dest,src ; Minne(S+L) -> register D tcycle = tpc + timem + trf + talu + tdmem + tmplx + trf Resultat från krets/minne passerar nästa register efter stigande flank hos klockan Hela klockcykeln tillgänglig för beräkning/access Fördröjer resultat klockcykel per steg Indikera vilken instruktion aktiv vid varje tidpunkt i respektive register Hur pipelining adderas till strukturen Lägg in register i dataflödet IR mellan instruktionsminne och registerfil Register mellan registerfil och ALU Timing hos pipeline Klockfrekvens begränsas av längsta väg från register till nästa register 8 Flera klockcyklers fördröjning Pipeline snitt Sdata fördröjs klockcykler innan minnet Måste få data i rätt klockcykel jämfört med minnesadress Styrsignaler måste hänga ihop med instruktionerna Pipeline snitt
9 Pipelining: Fler steg Hämta instruktion, Läs operand, Beräkna (ALU-operation), Minnesaccess, Skriv till registerfil Även IR är klockad Olika delar i instruktion behövs vid olika tidpunkter Borde ge upp till gånger högre klockfrekvens Ger andra problem Hoppaddress beräknas sent, Läsning från dataminne till register, Användning av registervärde innan värdet tillgängligt Exempel på olika pipelinedjup ARM (00) 0 Timingexempel Store instruktion Läs instruktion, hämta operander, beräkna adress, skriv i minnet ästa Store instruktion kan starta direkt stegs pipeline AMD (00) 8 steg Intel Pentium (00) Placera in register (flipflops) Kan dela upp instruktionen ytterligare (Ex steg) stegs pipeline i Haswell pipeline (0) till 9 steg
Problem vid load (minnesläsning) Typer av datakonflikt (data hazard) Måste ge registerfil tid att spara värde från minne Måste hålla destinationsadress en cykel längre Lösning: Stall (stoppa aktivitet i alla andra pipelinesteg) RAW (Read After Write) Läs efter skriv Föregående instruktion har inte sparat resultat som ska användas i nuvarande instruktion WAR (Write After Read) Skriv efter läsning Vanligen inget problem (kommer i senare föreläsning) WAW (Write After Write) Skriv efter skrivning Vanligen inget problem (kommer i senare föreläsning) Flera instruktioner exekveras delvis samtidigt Resultat från en instruktion ofta indata till nästa Resultat från en instruktion är inte alltid tillgänglig till nästa instruktion Jfr den inte hämtade instruktionen vid LOAD Kallas pipeline stall eller bubblor R0 uppdateras i instruktion i, läses i instruktion i+ Vid konflikter kan pipeline behöva stannas Data hazard exempel (RAW) Konflikter (hazards) R0 uppdateras i samma klockcykel som andra instruktionen vill läsa R0 Ex: Add r0,r,r Add r,r,r0 ; i (r0=r+r) ; i+ (r=r0+r) Registerbanker klarar inte skriva och läsa samma adress i en klockcykel Kräver stall? Läs R0 (i+) Går inte läsa och skriva i RF på samma adress samtidigt Spara R0 (i)
Hantering av RAW (mindre lämplig) Lös problemet genom att kräva minst en instruktioner mellan varje databeroende Programmeraren/kompilatorn måste hålla reda på databeroende och lägga till OP (no operation) => sänkt prestanda Bättre om annan instruktion utan kan placeras in istället (inte alltid möjligt) Op: ADD R0,R,R ; R0 = R+R Kompilerad kod inte portabel! 8 Klockcykel 0 Axel är aktivitet eller instruktion Tidsaxel vågrätt eller lodrätt Programmeraren behöver inte hålla reda på databeroende Exempel ADD R0,R,R ; R0 = R+R OP ADD R,R0,# ; R = R0+ ADD R,R0,# ; R = R0+ Klockcykel i i+ i+ i+ i+ i- I i+ i+ i+ I- I- I I+ i+ I- I- I- i i+ ADD R0,R,R OP ADD R,R0,# ADD R,R0,# = Instruction Fetch = Operand Fetch = Operation Execution = Operand Store S = Stall ADD Rx,Ry,Rz ; Rx = Ry+Rz stall mellan instruktion och => två ej utnyttjade möjligheter att utföra instruktioner motsvarande OP inlaggda mellan instruktion och Klockcykel 8 9 ADD R0,R,R ADD R,R,R ADD R,R,R S S ADD R,R,R = Instruction Fetch = Operand Fetch = Operation Execution = Operand Store S = Stall 0 Hantering av RAW (bäst) Samma händelser, olika sätt beskriva beroende på axlar i i+ i+ i+ Tvinga nästa instruktion vänta på data (sänker fortfarande prestanda) Alternativa sätt att beskriva händelser i CPU Op: ADD R0,R,R ; R0 = R+R OP ADD R,R0,# ; R = R0+ ADD R,R0,# ; R = R0+ Enkelt: STALL (ger bubblor i pipeline) ADD R,R0,# ; R = R0+ ADD R,R0,# ; R = R0+ Om pipelinedjup ändras måste programmet skriva om 9 Hantering av RAW (bättre) Det är inte en bugg, det är en feature... = Instruction Fetch = Operand Fetch = Operation Execution = Operand Store S = Stall Forward Skicka data direkt från resultat till operand (ej via register) Jämför destination för resultat hos nuvarande instruktion med källregister för nästa instruktion (styr mplx före s och s latch) Kräver mer logik (jämförare mellan destination och source samt multiplexer) Förlorar ingen klockcykel Klockcykel ADD R0,R,R ADD R,R,R ADD R,R,R ADD R,R,R = Instruction Fetch = Operand Fetch = Operation Execution = Operand Store
Forward, timing Styrkonflikt (mindre lämplig lösning) Exempel ADD R,R,R ; Destination R ADD R,R,R ; Källa R Det är ingen bugg, det är en feature... Räkna med att alla hopp även utför en eller möjligen två instruktioner efter hoppinstruktionen Känt som Delayed branch Kan behöva lägga till OP (=> sänkt prestanda) mov r,# bra next mov r,# ; utförs också : next: add r,r,r Styrkonflikt Execute påverkar programräknare (PC) Måste låta bli utföra två instruktioner Styrkonflikt (bättre lösning) ästa instruktion hämtas innan hopp avkodats Kräv inte att programmeraren tar hänsyn till problemet Undvik krav på kännedom om hur processorn ser ut inuti Försök korrigera/hantera problemet internt i processorn Kasta bort hämtade instruktioner Gäller även subrutinanrop, avbrott etc. Villkorliga hopp som inte tas kostar inget extra Ändrad arkitektur kan ge andra krav... Försök undvika kostnaden för hopp Minska antal ej utnyttjade klockcykler Svårt då adress till nästa instruktion inte känd i förväg
Villkorliga hopp, kostnad Detektera hopp redan vid operandhämtning Antag instruktion i är BRA Endast en klockcykel förloras I utförandefasen är den nya adressen beräknad Ett hopp har ofta inga operander som behöver hämtas I exemplet uppstår två tomma klockcykler (i+ och i+) Cykel Fetch instr. i- i- i (BRA) i+ i+ + + + + 0 8 9 Hämta operand i- i- i- i (BRA) i+ + + + Utför Spara resultat i- i- i- i- i- i- i- i- i (BRA) i- i (BRA) + + 8 Hoppet avkodad i klockcykel, instruktion hämtas i klockcykel Två bubblor, i+ och i+ = Instruction Fetch = Operand Fetch = Operation Execution = Operand Store 8 Fetch Instr. i (BRA) i+ (bubbla) + + + + Hämta operand i- i (BRA beräknad) i+ (bubbla) + + + Utför Spara resultat i- i- i- i- I i- i+ (bubbla) i i+ (bubbla) + + + 8 9 Olika typer Ovillkorliga hopp 0 Villkorliga hopp tillbaks i loopar Andra villkorliga hopp Hopp utförs alltid BRA label ; offset lagrad i IR som literal i instruktionen Typer av hopp Instruktion i är BRA 0 Cykel Alternativ beskrivning av bubblor i pipeline pga hopp Instruktion i- i- i i+ i+ + + + + Klockcykel Förbättra hantering av hopp Vid hopp uppstår bubblor i pipeline Hämtade men ej utförda instruktioner Hopp tas ofta Lika sannolikt hopp inte tas som att det tas Viktigt försöka minska påverkan av villkorliga hopp som tas
9 Kostnad för hopp Vanliga instruktioner tar klockcykel Sannolikhet för en hoppinstruktion är pb Sannolikhet för att hopp tas är pt Försök att minska antal hopp Antaganden Skapa instruktioner som tillåter villkorliga operationer ARM har t ex ADDEQ R,R,R Möjliggör sekvensiell kod med villkor utan hopp HP-PA har skip-next instruktion (villkorliga) Hopp som tas kostar b klockcykler extra Hopp som inte tas kostar inget extra (tar klockcykel) Medelvärde på antal klockcykler per instruktion Utför instruktionen endast om Z-flagga = 0 Utför inte nästa instruktion om villkor sant Kan skapa if then else kod utan hopp T ave =( p b) + p b pt (+b)+ p b ( p t ) =+ pb pt b 0 Effektivitet beroende på antal tagna hopp Pe = PbPt, dvs hur sannolikt är det att instruktionen är ett villkorligt hopp som tas Djup pipeline blir dyr när hopp tas Hopp som tas kostar b klockcykler extra Försök förutsäga hopp Om instruktionshämtaren i förväg vet att hopp kommer göras kan den hämta instruktioner från andra adresser Fördröjning kan då undvikas då rätt instruktioner kan hämtas och börja avkodas Omöjligt att förutsäga villkorliga hopp Kan gissa, mer eller mindre rätt Om rätt gissning görs förhindras förlorade klockcykler Kan i vissa processorer ange i instruktionen om hoppet oftast förväntas tas eller inte Statisk hopp prediktering Bestäms vid kompilering av koden
Att förutsäga hopp Fler än % av alla hopp missas Bättre lösning: Dynamisk hoppprediktering Fortfarande dyrt att gissa fel Kom ihåg om hoppet togs förra gången koden kördes Sparas internt i processorn för varje villkorlig hoppinstruktion som påträffas Hur branch prediction fungerar Statisk hopp-prediktering missar många hopp Tappar klockcykler i exemplet Begränsat antal adresser kan kommas ihåg. Samma problem som med cache Ännu bätte förutsägelse om inte bara det senaste hoppet används som förutsägelse Majoritet av visst antal av senaste exekveringar kan ange mest sannolika förutsägelse Hysteres kan användas Hopp prediktering, implementering Olika hopp har olika gissning Kan gissa om nästa instruktion utan att nuvarande instruktion lästs Problem med miss består i att instruktionen inte kan börja avkodas Lagra opcode från adress som inte förväntas läsas Måste kört koden innan tabellen fyllts (på samma sätt som för cache) Förbättrad Branch Target Buffer Spara gissning för varje enskilt villkorligt hopp Dyrt minne (associativt cacheminne) Om fel förutsägelse så finns opcode redan tillgänglig
Två nivåers branch predictions Resultat från flera villkorliga hopp kan vara korrelerade Vissa mönster kan finnas som kan säga mer om vilka hopp som sannolikt kommer hända www.liu.se Branch pattern history 8 Två nivåers branch prediction Använd mönstret av senaste villkorliga hopp för att välja en prediktor som användes senast detta mönstret sågs Har troligen gått genom samma sekvens av villkorliga hopp, och kommer då troligen göra samma val framöver