Warning
This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

6. Pipeline a hazardy

Osnova cvičení

  1. Fibonacciho posloupost na pipeline
  2. Bubble sort na pipeline

Co bych si měl na cvičení zopakovat/připravit

  1. Porozumět přednášce o pipeline procesoru a datových hazardech

Zkuste si program

.globl _start

.option norelax

.text
_start:

main:

    addi  x2,  x0, 10
    add   x11, x0, x2   // A : $11<-$2
    add   x12, x0, x2   // B : $12<-$2
    add   x13, x0, x2   // C : $13<-$2

    la x5, varx  // $5 = (byte*) &varx; 
    // The macro-instruction la is compiled as two following instructions:
    //addi  x5,  x0, 0x400

    lw    x1, 0(x5)     // $1 = *((int*)$5);
    add   x15, x0, x1   // D : $15<-$1
    add   x16, x0, x1   // E : $16<-$1
    add   x17, x0, x1   // F : $17<-$1
loop:
    ebreak
    beq    x0, x0, loop
    nop

.data
.org 0x400
varx:
	.word  0x1234

Odkrokujte si ho:

  1. napřed s vypnutým pipeline,
  2. poté si aktivujte pipeline, ale bez hazard unit.
  3. nakonec navolte pipeline s hazard unit.

Pozn. Datová a instrukční cache jsou zde nepodstatné, můžete je obě deaktivovat.

Sledujte nejen výsledné hodnoty v registrech, ale i případné stall stavy, je-li aktivní hazard unit.

  • Kdy instrukce označené A, B, C, D, E a F dají správné výsledky?
  • Kolik cyklů bude potřebovat celý program?

Počet cyklů Vašeho programu se v QtRVSim zobrazuje vpravo v okně procesoru.

Otázka k zamyšlení: Pokud QtRVSim potřeboval více cyklů hodin se zapnutým pipeline než bez něho, znamená to tedy, že pipeline procesor běží pomaleji, nebo ne?

Navrhněte vylepšení: Popřemýšlejte, jak program upravit, aby více vyhovoval pipeline zpracování. Lze v něm snížit počet stall, či ho modifikovat dokonce tak, aby běžel i bez hazard unit?

Náplň cvičení

Na 3. cvičení byl zadaný příklad na výpočet N-tého Fibonacciho čísla s ukládáním posloupnosti do paměti. Pro zopakování, předpis funkce

 F(n) = F(n-1) + F(n-2), for n > 2, and F(0) = 0, F(1) = 1.
a několik počátečních členů Fibonacciho řady: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,…

Modifikujte svůj program tak, aby správně běžel i na pipeline procesoru. Zapište jím 20 prvních členů posloupnosti, tj. hodnoty 0, 1, 1, 2, …, 4181 (0x1055), 6765 (0x1A6D) do paměti.

Můžete využít následující šablonu asembleru:

.globl _start
.set noat
.set noreorder

_start:
// Zde je misto pro Vas vlastni kod...
   addi t0, x0, 0x400   //  la t0, fibonacci bez hazardu

.data
.org 0x400
fibonacci:
	.word  0x1234

Program odlaďte:

  1. Nejdříve na simulátoru QtRVSim nakonfigurovaným na jednoduchý procesor bez vyrovnávací paměti a zřetězeného zpracování instrukcí (pipeline).
  2. Poté přepněte na zřetězené zpracování s jednotkou hazardů. Algoritmus by měl stále vydávat předpokládané výsledky.
  3. Následně vypněně jednotku detekce hazardů. Procesor se tím zjednoduší, ale algoritmus přestane vracet očekávané hodnoty.
  4. Zamyslete se, jak by asi měl kompilátor upravit kód pro zřetězený procesor s vypnutou detekcí hazardů, aby nadále vykonával stejnou funkci jako standardní RISC V. Upravte kód v assembleru tak, aby nedocházelo k nechtěnému vlivu datových hazardů, tj. musíte buď změnit pořadí instrukcí nebo vložit NOP instrukce.

Vaším úkolem bude dosáhnout minima použití NOP.

Zápis řady do paměti

Modifikujte předchozí program pro výpočet členů Fibonacciho posloupnosti, aby jednotlivé členy řady zapsal do datové paměti od návěští fibonacci (instrukce sw). Pro výpočet dalšího členu tentokrát využívejte předchozí členy načtené z paměti (instrukce lw). Vykonávání programu sledujte v simulátoru QtRVSim.

Kontrolní otázky:

  • Jak se realizuje instrukce add?
  • Jak se realizuje instrukce addi?
  • Jak se realizuje instrukce lw?
  • Jak se realizuje instrukce sw?
  • Kolik taktů trvá než je známa adresa větvení a jak se zjišťuje? (instrukce beq a bne)
  • Sledujte vykonání programu v simulátoru QtRVSim pro variantu bez pipeline, s pipeline bez a s zapnutou jednotkou řešení hazardů. Sledujte jak se liší doba vykonávání programu pro případ, kdy jsou hazardy řešené pozastavením, a případ, kdy je použitý forward. Pokuste se pro každou variantu navrhnout algoritmus, který je vykonán v nejkratším čase. Především se zaměřte na variantu bez a s řešením hazardů v hardware. Počet potřebných cyklů do dosažení instrukce break můžete odečíst například z počtu čtení z paměti programu spočítanému v okně programové vyrovnávací paměti.

Lineární kód pro sledování postupu instrukcí pipeline

Adresář s Makefile naleznete na cestě

/opt/apo/pipe-test

Testovací příklad

.globl _start
.text
.set noat
.set noreorder

_start:
  nop
  nop
  nop
  nop
  nop
  addi t0,x0,0
  addi t1,x0,0
  addi t2,x0,0
  addi t3,x0,0
  addi t4,x0,0
  addi t5,x0,0
  addi t6,x0,0
  addi s1,x0,0x11
  addi s2,x0,0x22
  addi s3,x0,0x33
  addi s4,x0,0x44
  addi s5,x0,0x55
  addi s6,x0,0x66
  addi s7,x0,0x77
  addi s8,x0,0x88
  addi s9,x0,0x99
  nop
  nop
  nop
_test:
  addi t0,s1,0     // registr t0 bude za čtyři takty nastaven na 0x1111
  // registr s1 změní hodnotu na 0x1133, ale v MipsPipeS tato
  // změna trvá ještě tři hodinové takty, následující dvě instrukce
  // vidí předchozí hodnotu registru
  addi s1,s1,0x22
  add  t1,x0,s1    // t1 se nastaví na starou hodnotu 0x1111
  add  t2,x0,s1    // t2 bude bez přeposílání také ještě nastaveno na 0x1111
  add  t3,x0,s1    // zápis s1 do registru proběhl, t3 bude nastaveno na 0x1133
  beq  x0,x0,skip
  // řídicí hazard
  // načtení dalších instrukcí a pak jejich zahození
  add  t5,x0,s1    
  add  t6,x0,s1    
  add  s2,x0,s1    
  add  s3,x0,s1    
skip:
  nop
  nop
  ebreak

courses/b35apo/tutorials/06/start.txt · Last modified: 2022/03/23 17:51 by pisa