Datorarkitektur med operativsystem Hantering av hazards i pipelines Lisa Arvidsson IDA2 Inlämningsdatum: 2018-12-05
Abstract En processor som använder pipelining kan exekvera ett flertal instruktioner under en klockcykel. På grund av den stora mängden av instruktioner som exekveras kan det uppstå problem, så kallade hazards. De tre olika konflikterna som kan uppstå är data hazard, kontroll hazard eller strukturell hazard. I rapporten diskuteras dessa olika typerna av hazards som kan ske om en pipeline arkitektur används och hur man kan hanterar konflikterna som uppstår. Introduktion När man talar om pipelining inom computing så handlar det om ett tillvägagångssätt som gör att operativsystemet i datorn kan utföra flera instruktioner samtidigt och därefter kan man uppnå bättre prestanda. Antal steg som en pipeline skall ha, bestäms helt av personen som designat processorn och kan därför variera. Men på grund av mängden av instruktioner som exekveras samtidigt kan det uppstå problem, hazards. Personen som gjort designen bör därför ha tänkt på svårigheterna man kan stöta på. I den här rapporten kommer vi diskutera strukturella hazards, data hazards och kontroll hazards samt hur man kan gå tillväga för att hantera dem problemen som uppstår. Diskussion Strukturella hazards Denna hazard uppstår när två eller flera instruktioner vill använda en resurs (minne, funktionell enhet) samtidigt och därför blir det ett stopp. För att undvika detta kan en stall (fördröjning) sättas in där problemet uppstår och man får en penalty på en cykel. Däremot finns det ett annat och mer hållbart sätt att undfly strukturella hazards. Detta sätt handlar om att man separerar cacheminnet så att ett cacheminne tar hand om instruktioner och det andra cacheminnet tar hand om data, istället för att använda ett och samma cacheminne, se figur 1. Detta leder till att flera instruktioner inte behöver använda en och samma resurs samtidigt och ingen strukturell hazard uppstår. Figur 1
Data hazards Om två instruktioner ska exekveras utan pipelining så görs detta i ordning, det vill säga först exekveras första instruktion färdigt och sen börjar andra instruktionen exekveras. Om man istället använder pipelines så kan det kan hända att den andra instruktionen behöver resultatet från den första instruktionen, som inte har exekverat färdigt än. Detta leder till att man får ett värde som inte är korrekt, på så vis kan problemet data hazard uppstå. Ahmed M. Mahran berättar i A handy systematic method for data hazards detection in an instruction set of a pipelined microprocessor att det finns tre olika typer av data hazards. Dessa delas in beroende på ordningen av läsa (read) och skriva (write) instruktionerna. Read After Write (RAW) hazard uppstår när en nyare instruktion vill använda data från en tidigare instruktion, men den tidigare instruktionen har inte exekverat klart. Vilket betyder att den nyare instruktionen kommer inte att få rätt värde från den tidigare instruktion och därmed få fel resultat. Write After Read (WAR) hazard förekommer om en nyare instruktion vill skriva över adressen innan den tidigare instruktionen har hämtat den. Detta betyder att man får fel adress och därmed fel data. Write After Write (WAW) hazard sker om den nyare instruktionen skriver till en adress innan den tidigare instruktionen skrivit till adressen. Det betyder att adressen inte innehåller rätt information. För att undvika data hazards kan man använda sig av re-schedule. Detta innebär att man ändrar ordningen på instruktionerna så att variabler som används i instruktionen efter inte blir påverkade. Ett exempel är att en instruktion med en beräknings operation som sparar ett värdet i ett register kan flyttas, och placeras ännu tidigare så att nästa instruktion som använder registrets resultat inte får fel. En annan metod som kan användas för att undvika data hazard kallas för forwarding eller bypassing. Tekniken innebär att man kompletterar med en hårdvara som tar resultatet direkt från till exempel ALUn istället för att vänta på att resultatet kommer till minnet. Denna komponent kan kallas för forwarding unit. I boken Computer Organization and Design: The Hardware/Software Interface, förklaras att en Forwarding enheten kan dock inte lösa alla konflikter. I fallet där operationen load sker före en beräknings operation, är resultatet inte tillgängligt förens ett steg senare vilket är försent för att kunna dra nytta av värdet. Därför måste pipeline stalls tillämpas och resultatet leder till att instruktionen efter, får en penalty på en klockcykel. Så om detta skulle ske kan den föregående metoden re-schedule vara ett bättre alternativ.
Kontroll hazards Denna hazard uppstår på grund av en hopp-instruktion så kallad branch instruktion. Efter att branch instruktionen har exekverats blir det stopp för att det är okänt vad som är nästa instruktion. Hoppet kommer exekvera om resultatet blir noll, men i och med att den inte vet resultatet innan nästa instruktion startar så kommer en kontroll hazard uppstå. Det finns flera olika sätt att undvika kontroll hazards, i den här rapporten kommer delayed branching och branch prediction diskuteras. Istället för att lägga in stalls, tills vi vet om hoppet ska göras (branch taken) eller om hoppet inte ska göras (branch not taken) så vill man med delayed branching att processorn ska göra någonting iallafall. Därför är det sagt att med delayed branching exekverar processorn alltid den instruktion som kommer efter hopp-instruktionen, och sedan kan koden ändra riktning om så behövs. Detta betyder att man får en penalty på en cykel mindre, det vill säga att det blir två cykler istället för tre vid ett villkorligt hopp och en cykel vid ett ovillkorligt hopp. Branch prediction är ett annat sätt man kan tillämpa för att undvika kontroll hazards. När man talar om branch prediction använder man ett tillvägagångssätt där man gör ett antagande. Det betyder att man alltså antar att nästa instruktion ska vara ett hopp alternativt ska inte vara ett hopp innan processorn vet om det är rätt instruktion. Om antagandet är rätt så får man en penalty på en cykel medan om gissningen är fel blir det en penalty på två cyklar, se figur 2. Figur 2 Inom branch prediction finns det två olika tekniker man kan använda för att göra ett antagande. Antingen använder man static prediction eller dynamic prediction. Om samma antagande sätts varje gång en branch instruktion exekveras kallas det för en static prediction. Medan om antagandet varierar och sätts till olika beroende på hur branch instruktionen bestämdes senast, talar man om dynamic prediction.
Använder man static prediction kan en metod appliceras där man antar att alla hopp görs beroende på operations koden (OPCODE). I artikeln A study of branch prediction strategies, redovisar James E. Smith skillnaden mellan att göra ett och samma antagande för alla hopp, jämförelsevis med att anta att alla hoppen görs om det är en operationskoden eller att anta att hoppen inte görs när det är en annan operationskod. Resultatet blev markant bättre och visade fall där noggrannhet på antagandet ökade från 65.4% till 98.5%. En annan teknik som redovisades och kan nyttjas i static prediction är en metod där man antar att alla baklänges branches görs men alla forward branches inte görs. Det vill säga att hopp till lägre adresser utförs och alla hopp till högre adresser utförs inte. Denna metod fungerade bra, men på ett program blev prestandan sämre. Vilket visar att olika metoder fungerar olika bra på olika program. När det gäller dynamic prediction kan man använda sig av en minnestabell som är tillgänglig när en branch instruktions ska utföras. Minnet innehåller adresser på de hopp-instruktioner som användes senast, där en bit visar om hoppet gjordes eller ej. Biten kan sedan användas för att göra ett antagande. Det kan dock hända att hopp-instruktionen inte fanns i tabellen, därför måste ett nytt antagande göras och en adress måste eventuellt skrivas över. Detta görs först med hjälp av ett static prediction, där ett antagande sätts. Sedan kan metoder som first-in first-out (FIFO) eller least-recently used (LRU) användas för att ersätta en adress. Kontroll hazards är ett mycket vanligt problem och viktigt att åtgärda så det finns många lösningar. Olika lösningar krävs till olika system. Utöver de metoder som diskuterats i rapporten, finns det många fler och fler utvecklas hela tiden. Slutsats Sammanfattningsvis kan man säga att varje hazard kan lösas på olika vis. Dock kan man vid varje tillfälle sätta in en stall, men detta är inte alltid den bästa lösningen. Därför bör rätt metod tillämpas beroende på vilken typ av hazard det handlar om och hur problemet ser ut. Personen som skapar designen bör därför ha i åtanke på vem som ska använda operativsystemet och vad den skall användas till, för att kunna uppnå den bästa prestanda.
Referenser Smith, J. ( 1998), A study of branch prediction strategies, Control Data Corporation Arden Hills, Minnesota, ACM New York, NY, USA Mahran, A. ( 2012), A handy systematic method for data hazards detection in an instruction set of a pipelined microprocessor, Computer and Systems Engineering Department, Faculty of Engineering, Alexandria University Patterson, D. and Hennessy, J. ( 2014), Data Hazards: Forwarding versus Stalling, Computer Organization and Design: The Hardware/Software Interface, Fifth Edition, SIDOR pp.303-316, Morgan Kaufmann Publishers In Exploiting data forwarding to reduce the power budget of VLIW embedded processors (2001) Proceedings Design, Automation and Test in Europe. Conference and Exhibition 2001, Design, Automation and Test in Europe, 2001. Conference and Exhibition 2001. Proceedings, Design, automation and test in Europe, p. 252. doi: 10.1109/DATE.2001.915034. Larsson E. (2018), Datorarkitektur med operativsystem, pipelining, https://www.eit.lth.se/fileadmin/eit/courses/eitf60/f%d6/f%d62.pdf (Hämtad 2018-11-26) Figur 1 och Figur 2: Larsson E. (2018), Datorarkitektur med operativsystem, pipelining, https://www.eit.lth.se/fileadmin/eit/courses/eitf60/f%d6/f%d62.pdf (Hämtad 2018-11-26)