NEKE NAPREDNE TEHNIKE KOD SAVREMENIH PROCESORA
----------------------------------------------

*) PREKLAPANJE INSTRUKCIJA (poznato i kao "protocna obrada", "pokretna
   traka", engl. PIPELINING): uobicajeno je da se u svakom trenutku u
   procesoru izvrsava samo jedna instrukcija. Medjutim, s obzirom da
   se svaka faza izvrsavanja instrukcije (dohvatanje, dekodiranje,
   izvrsavanje, cuvanje rezultata) obavlja u razlicitim jedinicama
   procesora, moguce je da istovremeno u procesoru bude vise
   instrukcija, svaka u razlicitoj fazi. Na primer, jedna instrukcija
   se dohvata, druga se vec dekodira, a treca izvrsava u ALU
   jedinici. Ovaj mehanizam podseca na pokretnu traku u fabrici. Na
   ovaj nacin se moze znacajno povecati ukupan broj instrukcija koje
   se mogu izvrsiti u svakoj sekundi. Naime, pretpostavimo
   najjednostavniji slucaj, da svakoj instrukciji treba po jedan
   ciklus za svaku od gore navedenih faza izvrsavanja. To znaci da ce
   se svaka instrukcija izvrsavati u cetiri ciklusa. Ukoliko imamo
   frekvenciju 1GHz, to znaci da cemo u svakoj sekundi moci da
   izvrsimo 250 miliona instrukcija. Medjutim, ako koristimo mehanizam
   preklapanja instrukcija, tada ce se prva instrukcija zavrsiti nakon
   cetvrtog ciklusa, a sledeca vec nakon petog, zatim sledeca nakon
   sestog, i td. Ukupan broj instrukcija koje se izvrse tokom jedne
   sekunde je 1 milijarda - 3. Ovo je skoro 4 puta vise u odnosu na
   prethodni slucaj.

   GRAFICKI PRIKAZ: (F - FETCH, D - DECODE, E - EXECUTE, W - WRITE)

   Sekvencijalno izvrsavanje:
     
   |-|-|-|-|-|-|-|-|-|-|-|-|
1   F D E W
2           F D E W
3	            F D E W


   Pipelining izvrsavanje:

   |-|-|-|-|-|-|-|-|-|-|-|-|
1   F D E W
2     F D E W
3       F D E W
4         F D E W
5           F D E W
6             F D E W
7               F D E W
8                 F D E W
9                   F D E W

   U gornjem primeru u 12 ciklusa klasicnim sekvencijalnim
   izvrsavanjem mozemo izvrsiti 3 instrukcije, dok koriscenjem
   preklapanja mozemo izvrsiti 9 instrukcija u istom vremenu.

   Naravno, ovo je prilicno idealizovan slucaj. U praksi, mnogi
   faktori mogu uticati na efikasnost preklapanja. Na primer, ukoliko
   neka faza neke instrukcije traje duze od jednog ciklusa, to moze da
   poremeti preklapanje i da privremeno zaustavi "pokretnu
   traku". Primeri situacija kada se ovo moze dogoditi su brojni:

   -) kada instrukcija nije u instrukcijskom kesu, pa je potrebno vise
      ciklusa za njeno dohvatanje
   -) u slucaju instrukcija nejednake sirine, neke instrukcije
      zahtevaju vise ciklusa za dohvatanje jer su duze
   -) dekodiranje moze biti slozenije u slucaju kompleksnih
      arhitektura
   -) Izvrsavanje slozenih instrukcija se cesto ne moze obaviti u
      jednom ciklusu
   -) Cuvanje rezultata moze zahtevati vise ciklusa u slucaju upisa u
      memoriju, dok je za upis u registar obicno dovoljan jedan ciklus

   Sledeci primer pokazuje kako postojanje instrukcije cije
   izvrsavanje zahteva vise ciklusa utice na protocnu obradu:

         
   |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
1   F D E W
2     F D E W
3       F D E E E E W
4         F D       E W
5           F       D E W
6                   F D E W
7                     F D E W
8                       F D E W
9                         F D E W

   Dakle, treca instrukcija zahteva vise vremena za fazu izvrsenja (4
   ciklusa). Zbog toga se pokretna traka zaustavlja, jer sledeca
   instrukcija nakon dekodiranja mora da ceka da se oslobodi ALU
   jedinica za izvrsenje.

   Jedan od cestih razloga za ovakve pojave je to sto instrukcija koja
   se dohvata nije u kesu, pa je njeno dohvatanje sporo. U tom slucaju
   pokretna traka moze da stane zato sto nema vise instrukcija koje su
   dohvacene. Ovaj problem se u velikoj meri resava tehnikom
   PRETHODNOG DOHVATANJA (engl. prefetching). Kod ove tehnike postoji
   bafer koji moze primiti veci broj instrukcija. U ovaj bafer se
   dohvata vise instrukcija odjednom, tako da procesor u svakom
   trenutku ima vise narednih instrukcija na raspolaganju. U slucaju
   da dodje do zastoja prilikom dohvatanja neke instrukcije, to se
   nece odmah odraziti na pokretnu traku, jer ce procesor imati
   dovoljno instrukcija u baferu.

   Jos jedna od tehnika koja se cesto koristi za resavanje ovakvih
   problema je tzv. IZVRSAVANJE VAN REDOSLEDA (engl. out-of-order
   execution). Procesor moze utvrditi da dve ili vise instrukcija ne
   zavise jedna od druge, pa im moze promeniti redosled. Na primer:

   add esi, edi
   mov eax, x
   add ecx, edx
   mov edx, esi

   Primetimo da druga instrukcija ni na koji nacin ne utice na ostale
   tri instrukcije, pa se njeno izvrsavanje moze pomeriti unapred ili
   unazad, bez promene rezultata. Na primer, mozemo imati sledeci
   redosled:

   add esi, edi
   add ecx, edx
   mov edx, esi
   mov eax, x

   Ovaj drugi redosled omogucava bolje preklapanje. Zaista, u prvom
   slucaju, druga instrukcija koja zahteva ucitavanje operanda iz
   memorije odlaze fazu izvrsavanja sledece dve instrukcije. U drugom
   slucaju se faza izvrsavanja instrukcije sa memorijskim operandom
   odlaze za kraj, tako da ostale instrukcije mogu da se izvrse bez
   zastoja na pokretnoj traci. Naravno, ovako jednostavne optimizacije
   cesto rade i prevodioci (kompajleri). Medjutim, jos bolji efekti se
   dobijaju ukoliko unutar procesora omogucimo izvrsavanje van
   redosleda na nivou pojedinacnih faza izvrsavanja
   instrukcije. Drugim recima, instrukcija koja je prva dohvacena ne
   mora prva i da se izvrsi; posmatraju se operandi od kojih
   instrukcija zavisi, kao i resursi koji su potrebni za svaku od faza
   izvrsavanja, na osnovu cega se odredjuje redosled faza izvrsavanja
   pojedinih instrukcija na pokretnoj traci. U prethodnom primeru:

   add esi, edi
   mov eax, x
   add ecx, edx
   mov edx, esi

   kada dodjemo do faze izvrsenja druge instrukcije (koja podrazumeva
   ucitavanje operanda x iz memorije, sto zahteva veci broj ciklusa),
   mi smo vec izvrsili dohvatanje cetvrte instrukcije i dekodiranje
   trece instrukcije. Kako treca i cetvrta instrukcija ne zavise od
   rezultata druge, mi mozemo izvrsavati trecu, a zatim i cetvrtu
   instrukciju dok druga ceka na svoj operand iz memorije:

   |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
1   F D E W
2     F D E         W
3       F D E W         
4         F D E W       



   Opisani problemi su u mnogo manjoj meri izrazeni kod RISC
   procesora, jer su kod njih obicno sve instrukcije jednake duzine i
   istog formata, a podrazumevaju jednostavne operacije ciji se
   operandi po pravilu nalaze u registrima i zahtevaju jedan ciklus u
   ALU jedinici. U slucaju CISC procesora, zbog velikog broja
   razlicitih formata, kao i zbog prisustva slozenih instrukcija cije
   se izvrsavanje prostire u velikom broju ciklusa implementacija
   efikasnog preklapanja instrukcija je znatno teze.

   Medjutim, cak i u slucaju RISC procesora postoje situacije u kojima
   dolazi do zaustavljanja pokretne trake:

   -) Ukoliko dve instrukcije pokusavaju da koriste isti resurs. Na
      primer, faze FETCH i WRITE mogu koristiti magistralu, jer obe
      mogu da podrazumevaju citanje/upis u memoriju. Ako imamo samo
      jednu magistralu, jasno je da instrukcija koja treba da bude u
      FETCH fazi mora da saceka dok instrukcija koja je u WRITE fazi
      ne zavrsi sa pristupom magistrali. Ovaj problem se moze resiti
      prethodno opisanom prefetching tehnikom, ali i tako sto imamo
      zaseban instrukcijski kes i kes za podatke kojima se moze
      pristupati istovremeno (putem posebnih magistrala). S obzirom da
      ce u vecini slucajeva instrukcija i podatak koji se koriste u
      odgovarajucim FETCH i WRITE fazama biti u kesu, a ne u glavnoj
      memoriji, pristup memorijskoj magistrali kao zajednickom resursu
      nece biti potreban, pa nece doci do zaustavljanja pokretne
      trake.

      Ovakve situacije koje mogu dovesti do zaustavljanja pokretne
      trake usled zahteva za istim resursom nazivaju se i STRUKTURNI
      RIZICI (engl. structural hazards).

   -) Ukoliko imamo dve uzastopne instrukcije kod kojih druga
      instrukcija kao ulazni operand koristi izlaz prve instrukcije.
      U tom slucaju faza izvrsenja druge instrukcije se preklapa sa
      fazom upisa rezultata prve, pa ne moze koristiti njen rezultat.
      Tehnika koja se koristi u ovom slucaju je tzv. PROSLEDJIVANJE
      REGISTRA (engl. register forwarding), poznata i kao
      PREMOSCAVANJE (engl. bypassing). Kod ove tehnike rezultat prve
      instrukcije se moze proslediti drugoj i pre nego sto se zvanicno
      upise u svoje odrediste (jer je on vec spreman u nekom
      akumulatoru na izlazu ALU jedinice, unutar procesora).

      Ovakve situacije koje mogu dovesti do zaustavljanja pokretne
      trake usled zavisnosti od rezultata prethodnih instrukcija
      nazivaju se i RIZICI PODATAKA (engl. data hazards).

   -) Ukoliko imamo instrukcije uslovnog skoka, tada ne znamo tacno
      koje ce instrukcije slediti nakon skoka -- one koje slede u
      memoriji, ili one koje se nalaze pocev od adrese na koju se
      skace. Ukoliko ucitamo pogresan niz instrukcija, sve sto je
      uradjeno sa njima (fetch, decode, ...) bice odbaceno, a pokretna
      traka bice zaustavljena dok se ne ucitaju prave instrukcije.
      Ova pojava se naziva i KAZNA SKOKA (engl. branch
      penalty).

      Ovakve situacije koje mogu dovesti do zaustavljanja pokretne
      trake usled pogresno ucitanih instrukcija prilikom uslovnog
      skoka nazivaju se RIZICI KONTROLE (engl. control hazards).

      Rizici kontrole se obicno razresavaju PREDIKCIJOM GRANANJA
      (engl. branch prediction). Ideja je da se unutar hardvera
      prilikom dohvatanja instrukcije skoka nekako predvidi koji ce
      rezultat biti (tj. da li ce da skoci ili ne), i da se za njom
      dohvataju odgovarajuce instrukcije. Cilj je da ovo predvidjanje
      bude tacno sa velikom verovatnocom. Obicno se koristi
      tzv. DINAMICKO PREDVIDJANJE, gde se koriste rezultati prethodnih
      n izvrsavanja te instrukcije da se predvidi sta ce se desiti u
      sledecem izvrsavanju. Na primer, ako posmatramo tri prethodna
      izvrsavanja, rezultat moze da bude da je do skoka zaista doslo
      0, 1, 2 ili 3 puta u 3 prethodna izvrsenja ove intrukcije. Ako
      je to 2 ili 3, tada pretpostavljamo da ce se desiti ponovo, a
      ako je 0 ili 1, onda pretpostavljamo da se ni ovog puta nece
      desiti skok. Pokaze se da je ova jednostavna tehnika
      predvidjanja dobra u preko 90% slucajeva.
   
 
*) SUPERSKALARNO IZVRSAVANJE
   -------------------------

Za razliku od preklapanja instrukcija koje omogucava izvrsavanje vise
instrukcija istovremeno tako sto ih deli na vise faza koje se onda
obavljaju na pokretnoj traci, superskalarno izvrsavanje podrazumeva
postojanje veceg broja odredjenih funkcionalnih jedinica u kojima se
instrukcije izvrsavaju (tipicno, vise ALU jedinica u istom procesoru).
Ovo znaci da vise instrukcija mogu istovremeno biti u fazi izvrsenja.
Sada procesor moze u svom baferu imati vise instrukcija koje je
dohvatio i dekodirao, koje se zatim analiziraju, utvrdjuju se
zavisnosti medju njima i na osnovu toga se biraju instrukcije koje se
salju razlicitim funkcionalnim jedinicama na izvrsenje.

Uobicajeno je da se ova tehnika kombinuje sa preklapanjem.

Prvi superskalarni procesor Intel-ove arhitekture bio je Pentium koji
je imao dve ALU jedinice.
