4. Pipelining 4. Pipelining Det finns en pipelinad biltvätt i Linköping spoltvätttork spoltvätt tork spolning tvätt tork De tre momenten tar lika lång tid Alla bilar går igenom samma program Väntetid 1/3 Genomströmning 3 OBS, vi får inte uppsnabbningen gratis. En del utrustning måste finnas på flera ställen! 1
kritik av OR-datorn 4. Pipelining Alternativa arkitekturer eller riktiga datorer - för många klockcykler, går att dock att snabba upp går att göra komplicerade instruktioner: sortering, matrisinvertering, RISC = reduced instruction set computer enkla,lika instruktioner => pipelining möjligt Vi börjar med OR LDA 000 12 ADD 100 7 STA 000 13 12 1 13 0 12 2 1 0 18,1,11 2,3,5,11 7,8,11 17,10 18,1,11 2,3,5,11 7,19,17 Hämta Absolut 1 30 M 2,3,5,11 7,25,11 27,32,33,11 34,12 LDA RESET 4 1 2
OR-datorn är för långsam! LDA 12 (exempelvis) Hämta : 3 CP 2 1 CP Absolut: 3 CP EXE: 4 CP Summa: 11 CP mem AR ADR XR SP DR TR IR 1 2 M mmem... Alltså 11 CPI (clocks per instructions) Vi siktar på 1 CPI! IN OUT Vad kan göras på OR-original? Parallellism Tryck ihop mikrokoden, dvs gör flera mop samtidigt Förhämtning: hämta nästa instruktion under exekvering av pågående instruktion ->M->dr dr->tr tr->ar status Exe av LDA pc-> ->M->dr dr->ir Hämta nästa instruktion mpc mpc mpc 2->mpc 3
Apropos klockfrekvensen x y Leta rätt på längsta tidsfördröjningen mellan två register. alla den T. Då gäller f < 1/T Brukar kallas kritisk väg Steg 1 Omplacering av register Ta bort onödiga register Förbättrat - Lång kritisk väg Pmem Dmem ADR XR data 1 IR 2 SP M Nya LDA 12 Hämta 1 CP mmem 2 1 CP AR Absolut 1 CP EXE 1 CP IN OUT 4
Skilda program- och dataminnen Bredare programminne, så att hela instruktionen kan hämtas på 1 CP Steg 2 OP M byte ADR pmem Nya LDA 12 Hämta 1 CP 2 1 CP Absolut XR SP IR 1 2 M byte mmem EXE 1 CP... AR OUT OUT Flera register! Registerfil R0 R1 R2 R3 R0 R1 R2 R3 Exempelvis: ADD R3,R2,R1 ; R3 = R2R1 5
RISC = reduced instruction set computer Vi avskaffar XR,SP och inför generella register Vi avskaffar flera a-moder per instruktion ADD Rx,Ry,Rz inga andra a-moder! LD Rx,(Ry) enda sättet att läsa i minnet! ST (Rx),Ry enda sättet att skriva i minnet! Vi avskaffar M och mikroprogrammering Mikroprogrammen försvinner inte utan finns på annan form i maskinen Steg 3 Hämtfasen har blivit HW pmem 1 ID innehåller 1-rads mprog IR byte ADD Rx,Ry,Rz LD Rx,(Ry) ST (Ry),Rx JMP N ADDI Rx,Ry, Instruction Decoder... Hämta 1CP Exe 1CP Förhämtning! 1 CPI, clock per instruction R0 R1 R2 R3 OUT OUT 6
ATMEL AVR Trevlig 8-bitars controller C-kompilator finns: avr-gcc Massor med kul I/O 0: LD R1, (R0) 1: ADD R3,R2,R1 2: JMP 0 3: XXX Pipelinediagram IR 0 1 LD 2 3 ADD JMP LD ADD 0-1 LD 1 inst/c JMP ger en i pipelinen 7
lassisk 5- stegs pipeline IF: instruction fetch hämta instr och ny RR: register read läs reg/beräkna hopp 1 Inspirerad av OpenRISC EXE: execute kör 2 MEM: read/write läs/skriv/ingenting WB: write back register skriv reg/ingenting Några instruktioner, alla 32b 6 5 5 5 ADD Rd, Ra, Rb ; Rd=RaRb OP d a b - 16 ADDI Rd, Ra, ; Rd=Ra OP d a 16 MOVHI Rd, ; RdH=,RdL=0 OP d - 16 LD Rd, (Ra) ; Rd=(Ra) OP d a 11 ST (Ra), Rb ; (Ra)=Rb OP a b SFEQ Ra, Rb ; F = (A==B)?1:0 OP - a b - JMP ; = OP 26 BF ; = F? : 4 OP 8
0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 0 rst 1 Några snälla instruktioner 1 I exemplet: Rn = n = 9 0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 4 ADD R3,R2,R1 1 1 1 2 9
0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 8 LD R6,(R5) 1 ADD R3,R2,R1 1 9 1 5 2 0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 C SFEQ R7,R8 1 LD R6,(R5) 1 7 8 9 5 ADD R3,R2,R1 3 10
0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 C:XXX 10:YYY 10 XXX 1 3 SFEQ R7,R8 1 7 8 F=0 LD R6,(R5) E=(95) ADD R3,R2,R1 DM(E) 3 0:ADD R3,R2,R1 4:LD R6,(R5) 8:SFEQ R7,R8 C:XXX 10:YYY 14:ZZZ YYY 14 1 XXX 2 SFEQ R7,R8 F=0 LD R6,(R5) DM(E) 11
Problem 1. Hopp, Oönskade instr kommer ibland in i pipelinen >Instruktionen efter ett hopp exekveras alltid >Ytterligare en instr. därefter ersätts med 2. Databeroenden, Reg läses i steg 2 o skrivs i steg 5 >data forwarding 3. Pipelinen måste i vissa lägen stängas av, stall Problem 1: Hopp 0:SFEQ ; sätter flaggan F 4:BF ; hoppar eventuellt till 20 8:XXX ; instr. exekveras alltid C:YYY... 20:ZZZ Vi bestämmer: Instruktionen XXX exekveras alltid Fördröjt hopp: XXX kan vara en nyttig instr flyttad hit av kompilatorn (software) 12
0:SFEQ 4:BF 8:XXX C:YYY... 20:ZZZ 8 BF XXX 1 4 20 SFEQ 1 F=? 20 0:SFEQ C 10 20 4:BF 20 8:XXX C:YYY YYY ZZZ... 20:ZZZ XXX 1 1 0:SFEQ 4:BF 8:XXX C:YYY... 20:ZZZ BF 2 4=20 XXX 2 SFEQ F=1 BF SFEQ 13
Pipelinediagram 0 4 SFEQ 8 BF SFEQ C XXX BF SFEQ 20 XXX BF SFEQ Instr efter hoppet exekveras alltid Vid taget hopp måste en muxas in Diskussion: Hur ska de två muxarna i första steget styras? if ((.op==bf and F==1) or (.op==j)) /* taget hopp */ = ; = 2; else // annan instr, F=0 = pmem; = 4; Problem 2: Databeroende 0:ADD R5,R2,R1 4:ADD R8,R5,R5 Farlig situation, som måste åtgärdas direkt! Data Hazard 8:MUL R3,R5,R5 Problemet beror på att det tar flera klockcykler innan registret R5 uppdateras! 14
Antag Rx = x 0:ADD R5,R2,R1 4:ADD R8,R5,R5 Data hazard Data forwarding 1 Registerfilen kan innehålla gamla data! Var kan nya resultat finnas?, / MUL R3,R5,R5 2 ADD R8,R5,R5 ADD R5,R2,R1 5 5 = gamla R5 3=nya R5 5 5 3 3 3 / Hur ska muxarna styras? if.op == instruktion som läser reg. if.op == instruktion som skriver reg. if.a ==.d muxarna = ; if.op == instruktion som läser reg. if.op == instruktion som skriver reg. if.a ==.d muxarna = ; 15
Problem 3: Stall 0:LD R3,(R2) ; läs från minnet 4:ADD R4,R3,R3 ; Problemet beror på att minnet sitter 1 klockcykel efter -n. 8 0:LD R3,(R2) 4:ADD R4,R3,R3 8 0:LD R3,(R2) 4:ADD R4,R3,R3 Stall 1 ADD R4,R3,R3 1 ADD R4,R3,R3 2 LD R3,(R2) 1 LD R3,(R2) 16
8 hopp stall hopp stall ADD R4,R3,R3 LD R3,(R2) pmem stall Pipeline stall -> Behåll Behåll 17