Przetwarzanie potokowe – pipelining
Transkrypt
Przetwarzanie potokowe – pipelining
Przetwarzanie potokowe – pipelining (cz˛eść A) – p. 1/15 Przypomnienie - implementacja jednocyklowa 4 Add Add Data PC Address Instruction Instruction memory Register # Registers Register # ALU Address Data memory Register # Data – p. 2/15 Wst˛ep W implementacjach prezentowanych tydzień temu w jednym momencie wykonuje sie˛ tylko jednen rozkaz. Jego wykonanie przebiega w kilku fazach. W każdej fazie używana jest tylko cz˛eść układów logicznych. Pomysł: w momencie gdy pierwszy rozkaz rozpoczyna druga˛ faz˛e, drugi zaczyna pierwsza; ˛ gdy pierwszy zaczyna trzecia, ˛ drugi zaczyna druga, ˛ a trzeci pierwsza, ˛ itd. W efekcie w jednym momencie wykonuje sie˛ tyle rozkazów ile jest faz. Każdy wykonywany rozkaz znajduje sie˛ w innej fazie. Taka˛ technik˛e nazywamy przetwarzaniem potokowym (ang. pipelining). W przetwarzaniu potokowym nie przyspieszamy wykonania pojedynczego rozkazu (wrecz ˛ przeciwnie!). Zysk dzieki ˛ urównolegleniu wykonywanie operacji. – p. 3/15 MIPS - fazy wykonania rozkazu Wykonanie rozkazu podzielimy na 5 faz: Pobranie rozkazu z pamieci ˛ (IF, instruction fetch) - 200ps Dekodowanie rozkazu i odczyt rejestrów (ID, instruction decode) - 100 ps Wykonanie operacji typu R lub wyliczenie adresu (EX, execute) - 200 ps Operacja na pamieci ˛ (MEM, memory) - 200 ps Zapis do rejestru (WB, write back) - 100 ps – p. 4/15 Porównanie Program execution Time order (in instructions) lw $1, 100($0) 200 Instruction Reg fetch lw $2, 200($0) 400 600 Data access ALU 800 1000 1200 1400 ALU Data access 1600 1800 Reg Instruction Reg fetch 800 ps lw $3, 300($0) Reg Instruction fetch 800 ps 800 ps Program execution Time order (in instructions) 200 400 600 Instruction fetch Reg lw $2, 200($0) 200 ps Instruction fetch Reg 200 ps Instruction fetch lw $1, 100($0) lw $3, 300($0) ALU 800 Data access ALU Reg 1000 1200 1400 Reg Data access ALU Reg Data access Reg 200 ps 200 ps 200 ps 200 ps 200 ps – p. 5/15 Projektowanie listy rozkazów Lista rozkazów MIPS została zaprojektowana z myśla˛ o przetwarzaniu potokowym. Stała długość rozkazów ułatwia ich pobieranie. Mała liczba formatów rozkazów. Rejestry źródłowe w tych samych miejscach - rejestry można odczytywać równolegle z dekodowaniem rozkazu. Operacje na pamieci ˛ wykonuja˛ tylko rozkazy lw, sw (i ich warianty). – p. 6/15 Hazardy Hazardy strukturalne Dwa rozkazy chca˛ w tej samej chwili skorzystać z tego samego zasobu (np. ALU, pamieć, ˛ rejestry) Hazardy danych. Rozkaz potrzebuje rejestru, który zapisuje poprzedni rozkaz. Np. add $s0, $t0, $t1 add $t2, $s0, $t3 Hazardy sterowania. W przypadku rozkazu skoku nie wiadomo, który rozkaz należy pobrać jako nastepny. ˛ Szczególnie trudne w przypadku skoków warunkowych. – p. 7/15 Hazardy strukturalne W zasadzie problem nie wystepuje ˛ w przypadku MIPS. Pojawiłby sie, ˛ gdybyśmy nie rozdzieli pamieci: ˛ gdy lw, sw próbuja˛ odczytać dana˛ z pamieci ˛ kolejny rozkaz nie może sie˛ pobrać. Rozdzielenie pamieci ˛ na pamieć ˛ rozkazów i danych pomaga zatem projektować przetwarzanie potokowe. W praktyce rozdziela sie˛ nie tyle pamieć ˛ główna˛ co pamieć ˛ podreczn ˛ a. ˛ – p. 8/15 Hazardy danych Np. add $s0, $t0, $t1 add $t2, $s0, $t3 $s0 jest zapisywany dopiero w piatej ˛ fazie pierwszego rozkazu Drugi rozkaz potrzebuje go już dwa cykle wcześniej! Rozwiazanie ˛ kiepskie: opóźnić (jakoś) wykonanie drugiego rozkazu o dwa cykle (dodać dwa „babelki”). ˛ Rozwiazanie ˛ programowe: reorganizacja kodu (np. przez kompilator) - trudne. Rozwiazanie ˛ sprz˛etowe: forwarding (bypassing) Program execution Time order (in instructions) add $s0, $t0, $t1 sub $t2, $s0, $t3 400 200 IF 600 800 ID EX MEM IF ID EX 1000 WB MEM WB – p. 9/15 Hazardy danych - cd. Forwarding nie eliminuje wszystkich hazardów danych. Program execution Time order (in instructions) lw $s0, 20($t1) 400 200 IF ID bubble sub $t2, $s0, $t3 800 600 EX bubble IF MEM bubble ID 1000 1200 1400 WB bubble EX bubble MEM WB – p. 10/15 Hazardy danych - reorganizacja kodu lw lw add sw lw add sw $t1, $t2, $t3, $t3, $t4, $t5, $t5, 0($t0) 4($t0) $t1, $t2 12($t0) 8($t0) $t1, $t4 16($t0) lw lw lw add sw add sw $t1, $t2, $t4, $t3, $t3, $t5, $t5, 0($t0) 4($t0) 8($t0) $t1, $t2 12($t0) $t1, $t4 16($t0) Z lewej strony 2 hazardy (rozkazy add) – pozostałe eliminowane przez forwarding. Z prawej – brak hazardów. – p. 11/15 Hazardy sterowania Załóżmy, że potrafimy w drugiej fazie wykonywania beq porównać rejestry, wyliczyć adres i ustawić nowy PC Nawet wtedy musimy opóźnić potok: Program execution Time order (in instructions) add $4, $5, $6 beq $1, $2, 40 200 Instruction fetch 200 ps 400 Reg 600 ALU Instruction fetch Reg 800 Data access ALU 1000 1200 Reg Data access Reg bubble bubble bubble bubble or $7, $8, $9 400 ps Instruction fetch 1400 Reg ALU bubble Data access Reg – p. 12/15 Hazardy sterowania - przewidywanie skoków Jedno z rozwiaza ˛ ń: przewidywanie skoków Np. zakładamy, że skoki sie˛ nie wykonuja˛ Program execution Time order (in instructions) add $4, $5, $6 beq $1, $2, 40 200 Instruction fetch 200 ps lw $3, 300($0) beq $1, $2, 40 Reg 200 Instruction fetch 200 ps 600 Reg Reg ALU Instruction fetch Reg ALU 1000 400 ps Instruction fetch Reg 1200 1400 Reg Data access Reg bubble bubble bubble bubble or $7, $8, $9 1400 Reg Data access ALU 800 Data access 1200 Reg Reg 600 1000 Data access ALU Instruction fetch 400 800 Data access ALU Instruction fetch 200 ps Program execution Time order (in instructions) add $4, $5, $6 400 Reg ALU bubble Data access Reg – p. 13/15 Hazardy sterowania - przewidywanie skoków Można zakładać, że niektóre skoki sie˛ wykonuja˛ (np. te skaczace ˛ wstecz), a inne nie. Przewidywanie może być też dynamiczne – jeśli podczas poprzedniego przejścia przez rozkaz skok sie˛ wykonał, to teraz też zakładamy, że sie˛ wykona. Można prowadzić historie˛ kilku ostatnich wykonań. Potrzebne oczywiście dodatkowe układy logiczne. Dobrze zorganizowane przewidywanie dynamiczne daje ponad 90% skuteczność! Inne rozwiazanie: ˛ skoki opóźnione (stosowane naprawde˛ w MIPS, ale niewidoczne dla programisty asemblerowego). – p. 14/15 Przetwarzanie potokowe: podsumowanie Przetwarzanie potokowe (pipelining) poprawia wydajność dzieki ˛ urównolegleniu wykonywania rozkazów. Pojedynczy rozkaz nie wykonuje sie˛ szybciej niż w procesorze jednocyklowym (a wrecz ˛ przeciwnie, bo przetwarzanie potokowe wprowadza pewne opóźnienia) Źródła problemów: współdzielenie pewnych układów, dane, sterowanie. Projektujac ˛ liste˛ rozkazów trzeba robić to pod katem ˛ przetwarzania potokowego. – p. 15/15