• Keine Ergebnisse gefunden

swap $t1, lock

N/A
N/A
Protected

Academic year: 2022

Aktie "swap $t1, lock"

Copied!
35
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Synchronisation

(2)

Data‐Race

Prozessor 1:  berechne x = x + 2

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x

Gemeinsamer Speicher

Variable x Prozessor 2:  berechne x = x – 1

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x

Es gelte zu Beginn: x=10 Gilt nach Durchlauf beider  Code‐Abschnitte immer  x=11?

(3)

Problem: Zugriff auf x ist nicht atomar

Prozessor 1:  berechne x = x + 2

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x

Prozessor 2:  berechne x = x – 1

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x

Zeit

Inhalt von x 10

(4)

Mögliche Lösung: Atomic‐Swap

Speicher

Variable lock 1.) Speicherinhalt lock in Register $t1 kopieren

2.) Alten Wert von $t1 nach lock kopieren

swap $t1, lock

Beispiel

$t1 lock

Vor Ausführung von swap 1 0

Nach Ausführung von swap 0 1

MIPS‐ISA hat kein swap, dennoch gibt es andere ISAs die so einen Befehl haben.

Also, zunächst ein Beispiel, wie man mittels swap synchronisieren kann.

swap ist hierbei atomar, d.h. während des swap wird jeglicher Speicherzugriff anderer  Prozesse verzögert bis swap vollständig ausgeführt wurde!

(5)

Mögliche Lösung: Atomic‐Swap

Prozessor 1:  berechne x = x + 2

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

Gemeinsamer Speicher

Variable x

Variable lock (initial=0) Prozessor 2:  berechne x = x – 1

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

(6)

Mögliche Lösung: Atomic‐Swap

Prozessor 1:  berechne x = x + 2

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei Prozessor 2:  berechne x = x – 1

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

Zeit x 10 lock

0

(7)

Weitere Lösung: Load Linked und Store Conditional

MIPS‐ISA hat ein Load‐Linked (ll) und Store‐Conditional (sc).

Also, wie kann man mit ll und sc synchronisieren?

Speicher

Variable lock Lade den Inhalt der Speicherstelle 0($s1) in das 

Register $t1 

ll $t1, 0($s1) # load linked

sc $t0, 0($s1) # store conditional 1. Wenn seit dem letztem load linked keiner 

auf den Speicherblock zugegriffen hat , dann  Speichere den Inhalt von Register $t0 auf die  Speicherstelle 0($s1) und setze $t0 auf 1.

2. Sonst lasse den Speicherblock unberührt  und setze $t0 auf 0.

(8)

Weitere Lösung: Load Linked und Store Conditional

Prozessor 1:  berechne x = x + 2

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, 2 # $t0 = $t0 + 2 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Gemeinsamer Speicher

Variable x

Prozessor 2:  berechne x = x – 1

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, -1 # $t0 = $t0 – 1 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

(9)

Weitere Lösung: Load Linked und Store Conditional

Prozessor 1:  berechne x = x + 2

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, 2 # $t0 = $t0 + 2 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Prozessor 2:  berechne x = x – 1

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, -1 # $t0 = $t0 – 1 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Zeit x 10

(10)

Zusammenfassung der neuen Befehle

Instruktuion Beispiel Bedeutung

ll ll $s1, 0($s0) Lade den Inhalt von Adresse 0($s0) in 

$s1 und starte eine atomare Read‐

Modify‐Write‐Operation.

sc sc $t0, 0($s0)  Speichere den Inhalt von $t0 auf  Adresse 0($s0), wenn seit dem 

letzten ll nicht von einem anderen  Prozess auf den Speicherblock 

zugegriffen wurde, der das 

adressierte Word enthält. Setze $t0  auf 1 in diesem Fall. 

Ansonsten überschreibe den 

Speicherbereich nicht und setze $t0  auf 0.

(11)

Quiz für den Quizmaster

Realisiere swap Register, Adresse mit ll und sc.

Erinnerung:

swap tauscht Speicher‐

inhalt und Registerinhalt  atomar aus.

Das Register sei $s0 Die Adresse sei 0($s1) Das temporäre

Register sei $t0

(12)

Exceptions

(13)

Motivation: Behandlung von Overflows

Was war nochmal ein Overflow? Beispiel mit 8‐Bit‐Zahlen:

01011010 (= 90) + 01100111 (=103) --- 11000001 (=-63)

Die bisher behandelten ganzzahligen Arithmetik‐Instruktionen (z.B. 

addaddi und sub ) können Overflow erzeugen.

Was wenn so ein Overflow auftritt? Einfach ignorieren?

Für jeden Overflow sollte eine Ausnahmebehandlungsroutine  aufgerufen werden, die dann entscheidet was zu tun ist. 

Anschließend kann der normale Code wieder ausgeführt werden.

Eine solche Ausnahmebehandlung wird über Exceptions realisiert.

(14)

Beispiele für Exceptions

Von außen ausgelöste Exceptions nennt man auch Interrupts

Ereignistyp Ausgelöst durch

den Prozessor?

Interrupt

Anfrage eines I/O Gerätes nein X

System‐Call ja

Arithmetischer Overflow ja Verwendung einer undefinierten

Instruktion

ja

Hardwarefehler ja/nein (X)

... ...

(15)

Behandlung von Exceptions

Genereller Ablauf:

Exception‐Handler

Aktuell laufendes  Programm

Speicher

(1) Exception

(2) Sichere $pc (3) Springe zum

Exception‐Handler (4) Behandle die 

Exception (5) springe ggf.

wieder zurück.

Rücksprung mit gesichertem $pc möglich.

Woher weis die CPU  wo der Exception‐

Handler liegt?

(16)

Behandlung von Exceptions

Möglichkeit 1: Interrupt‐Vektor‐Tabelle

Speichere Adresse der aktuellen  Programmausführung in einem 

speziellen Register EPC.

Wähle aus der Interrupt‐Vektor‐

Tabelle die Adresse des Handlers  für diesen Exception‐Typ  und 

springe dort hin.

Exception‐

Typ

Adresse des  Exception‐

Handlers Undefinded

Instruction

0x8000 0000 Arithmetic

Overflow

0x8000 0180

... ...

Handler‐Routine springt nach  Exception‐Behandlung ggf. zurück  in den normalen Code, d.h. an die  Programminstruktion auf die EPC 

zeigt.

Interrupt‐Vektor‐Tabelle

(17)

Behandlung von Exceptions

Möglichkeit 2: Cause‐Register (das ist die MIPS‐Variante)

Speichere Adresse der aktuellen  Programmausführung in einem 

speziellen Register EPC.

Speichere den Exception‐Typ in  einem  speziellen Cause‐Register.

Springe an die Adresse des einen  Exception‐Handlers.

Der Exception‐Handler behandelt  den im Cause‐Register 

beschriebenen Exception‐Typ. 

Routine springt nach Exception‐

Behandlung ggf. zurück in den  normalen Code, d.h. an die  Programminstruktion auf die

EPC zeigt.

Nummer Exception‐Typ (Grund) 0 Interrupt (Hardware)

4 Address‐Error (load or fetch) 5 Address‐Error (store)

6 Bus‐Error (fetch) 7 Bus‐Error (store)

8 System‐Call

9 Break‐Point

10 Reserved Instruction

11 Coprocessor Unimplemented 12 Arithmetic Overflow

13 Trap

15 Floating‐Point‐Exception

MIPS Exception‐Codes

(18)

PC

MIPS Hardware‐Realisierung von Exceptions?

CPU Coprocessor 1 (FPU)

Coprocessor 0 (Traps and Memory)

$0 . . .

$31 Arithmetic

Unit

Multiply Divide

$0 . . .

$31

Arithmetic Unit Registers Registers

Lo Hi

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14) Registers

Memory

Es gibt einen  weiteren  Coprozessor

(19)

Beispiel: Aufruf des Exception‐Handlers

Coprocessor 0 (Traps and Memory) Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Exception-Handler beginnt immer hier 0x80000180 : ...

0x80000184 : ...

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

$pc vor Exception:

6       2 Exception‐Code für  Arithmetic Overflow  ist 12.

$pc nach Exception:

(20)

Beispiel: Handling der Exception

Coprocessor 0 (Traps and Memory)

40000014 Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$zero,0# Problem gelöst 0x80000184 : eret # Rücksprung

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

$pc zur Behandlung:

$pc nach Behandlung:

(21)

Weitere Exceptions während des Handlings?

Coprocessor 0 (Traps and Memory)

40000014 Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$zero,0# Problem gelöst 0x80000184 : eret # Rücksprung

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

$pc zur Behandlung:

$pc nach Behandlung:

Möglichkeiten, z.B.:

Exception‐Handler erzeugt selber eine Exception

Anfrage eines IO‐Gerätes

(22)

Exceptions während des Handlings abgeschaltet

Coprocessor 0 (Traps and Memory) Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$zero,0# Problem gelöst 0x80000184 : eret # Rücksprung

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14) 15       8      1 0

Exception‐Level‐Bit:

0 = Exceptions werden berücksichtigt

1 = Exceptions werden nicht berücksichtigt

Wird bei Sprung in den Exception‐Handler immer gesetzt.

Bei Aufruf von eretwird das Bit wieder gelöscht

(23)

Status erlaubt auch das Maskieren von Interrupts

Coprocessor 0 (Traps and Memory) Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$zero,0# Problem gelöst 0x80000184 : eret # Rücksprung

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14) 15       8      1 0

Interrupt‐Maske

Die Bits einer  Interrupt‐Maske bestimmen welche Interrupt‐

Level Exceptions erzeugen dür‐

fen und welche ignoriert wer‐

den.

Jeder mögliche Interrupt ist einem Interrupt‐Level zugeord‐

net.

Mit Bit 0 des Status‐

Registers können  Interrupts generell  ein‐ und ausgeschaltet  werden.

(24)

Pending‐Interrupts

Coprocessor 0 (Traps and Memory)

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Exception-Handler beginnt immer hier 0x80000180 : ...

0x80000184 : ...

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14) 15      8       6       2

Exception‐Code

Registers Pending

Interrupts

Alle ankommenden Interrupts (auch ausmaskierte) setzen im Cause‐Register das

Pending‐Flag ihres Interrupt‐

Levels.

Wird das Masken‐Bit (oder das generelle Interrupt‐Bit) später wieder aktiviert, löst das

Pending‐Bit dann den Interrupt auf der CPU aus.

(25)

Zugriff auf die Coprocesor‐0‐Register

Coprocessor 0 (Traps and Memory)

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14) Registers

Erinnerung: Für den FPU‐Coprozessor (Coprozessor 1) hatten wir:

mfc1 : laden von FP‐Coprozessor‐Register in CPU‐Register mtc1 : laden von CPU‐Register in FP‐Coprozessor‐Register Analoge Instruktionen für den Coprozessor 0:

mfc0 : laden von Coprozessor0‐Register in CPU‐Register mtc0 : laden von CPU‐Register in Coprozessor0‐Register Beispiele:

mfc0 $s0, $13 # $s0=Coprozessor-Register 13 mtc0 $13, $s0 # Coprozessor-Register 13=$s0

(26)

Beispiel für Coprocessor 0 Register‐Zugriff

Coprocessor 0 (Traps and Memory) Registers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 : ...

...

# Ein etwas besserer Exception-Handler

# Exception auslösende Instruktion einfach überspringen 0x80000180 : mfc0 $k0,$14 # $k0 = EPC 0x80000184 : addi $k0,$k0,4 # $k0 = EPC+4 0x80000188 : mtc0 $14,$k0 # EPC=EPC+4 0x8000018c : eret # Rücksprung

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

$pc zur Behandlung:

$pc nach Behandlung:

Beachte: Register‐Satz‐

Konvention: $k0 und $k1  sind für OS‐Funktionen reserviert. Behandeln von Exceptions ist eine OS‐

Funktion.

(27)

Traps

Trap – eine Instruktion, die eine Bedingung testet und eine 

Exception vom Typ 13 (Trap) auslöst, wenn die Bedingung erfüllt ist.

Trap‐Instruktionen am Beispiel:

teq $s0,$s1 # Trap‐Exception, wenn $s0 = $s1 teqi $s0,42 # Trap‐Exception, wenn $s0 = 42 tne $s0,$s1 # Trap‐Exception, wenn $s0 != $s1 tnei $s0,42 # Trap‐Exception, wenn $s0 != 42 tge $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1

tgeu $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1 (unsigned) tgei $s0,$42 # Trap‐Exception, wenn $s0 >= 42

tgeiu $s0,42 # Trap‐Exception, wenn $s0 >= 42 (unsigned) tlt $s0,$s1 # Trap‐Exception, wenn $s0 < $s1

tltu $s0,$s1 # Trap‐Exception, wenn $s0 < $s1 (unsigned) tlti $s0,$42 # Trap‐Exception, wenn $s0 < 42

tltiu $s0,42 # Trap‐Exception, wenn $s0 < 42 (unsigned)

(28)

System‐Call – Mechanismus zum Aufrufen von Betriebssystem‐

funktionen.

Anwendung der Instruktion syscall am Beispiel:

addi $v0, $zero, 1 # Lade System‐Call‐Code in $v0

# hier System‐Call‐Code 1 für den

# Systemcall print_int addi $a0, $zero, 42 # Lade das Argument für den

# System‐Call nach $a0.

# Hier soll die Zahl 42

# ausgegeben werden.

syscall # Rufe den System‐Call auf

# dies führt zu einer Exception

# vom Typ 8 (System‐Call)

System‐Calls

(29)

In SPIM/MARS verfügbare System‐Calls

(30)

Zusammenfassung der neuen Befehle

Instruktuion Bedeutung

eret Springe aus Exception‐Handler zurück. Setzt  Exception‐Level‐Bit im Status‐Register wieder  auf 0.

teq, teqi, tne, tnei, tge, tgeu, tgei, tgeiu, tlt, tltu, tlti, tltiu

Löse Trap‐Exception aus, wenn die Bedingung  erfüllt ist.

Beispiel: teq $s0, $s1 löst einen Trap aus,  wenn $s0 = $s1 gilt.

syscall Rufe System‐Call mit der in $v0 gespeicherten  Nummer auf. Parameter des System‐Calls

werden in $a0 und $a1 übergeben.

Beispiel: syscall gibt eine 42 auf dem 

Bildschirm aus, wenn $v0 = 1 (print_int) und 

$a0 = 42.

(31)

Unsigned Arithmetik‐Instruktionen

Zu den bisher behandelten Arithmetik‐Instruktionen gibt es auch  noch unsigned Varianten, die keine Overflow‐Exception erzeugen.

Beispiel:

# Es gelte $s2 = 0x7fffffff addu $s1,$s2,$s2 # erzeugt *keine*

# Overflow-Exception!

(32)

Signed und ihre Unsigend‐Varianten

Signed

Instruktion

kann 

Overflow  erzeugen

Unsigned Vertreter

kann 

Overflow  erzeugen

add ja addu nein

addi ja addiu nein

div nein divu nein

mult nein multu nein

mul nein

madd nein maddu nein

msub nein msubu nein

sub ja subu nein

(33)

Pseudoinstruktionen, Direktiven und Makros

(34)

Motivation für Pseudoinstruktionen

Wir hatten häufiger schon

addi $s1,$zero,wert # $s1=wert

Eine Instruktion li (Load‐Immediate) wäre doch nachvollziebarer li $s1,wert # $s1=wert

MIPS als ISA aus dem RISC‐Lager versucht aber den Instruktion‐Set  möglichst klein zu halten. Damit ist so was wie ein li in der ISA  nicht eingebaut. Kann man ja mit einem addi und dem $zero

Register ausdrücken.

Dennoch gibt es in MIPS oben genannte Instruktion. Wo kommt die  her?

Das ist eine sogenannte Pseudoinstruktion, die der Assembler in  Instruktionen der MIPS ISA übersetzt.

(35)

Umsetzung von Pseudoinstruktionen

Wie würde folgende move Instruktion vom Assembler umgesetzt?

move $s1,$s2 # Pseudoinstruktion $s1=$s2

Wie würde folgende blt Instruktion vom Assembler umgesetzt?

blt $s1,$s2, Label # Springe nach Label,

# wenn $s1<$s2 gilt

Beachte: Registerkonvention. Pseudoinstruktionen die ein Register  zum Zwischenspeichern von Ergebnissen brauchen, benutzen dazu  das Register $at (Assembler‐Temporary)

Referenzen

ÄHNLICHE DOKUMENTE

Korrekte Software: Grundlagen und Methoden Vorlesung 11 vom 02.07.20 Spezifikation von Funktionen.. Serge Autexier, Christoph Lüth Universität Bremen

Participants can maintain individual knowledge structures on their peers (PCs), while sharing knowledge in ways such that administration efforts are low, but knowledge sharing

L ’objectif de cet article est d’analyser l’impact de la récente crise financière internationale sur les marchés des dérivés de crédit et spécialement, le marché japonais

To evaluate ex–ante forecasting performance for particular short, medium and long term rates and for the level, slope and curvature of the swap term structure, we rely on measures

We document that banks are less likely to syndicate loans and retain a larger loan fraction once CDS are actively traded on the borrower’s debt.. We then discern the risk management

Nutzer, die sich ausschließlich für die unbekannten Orte interessieren und über unser Tool nicht in Kontakt mit anderen Nutzern kommen möchten, können natürlich einstellen,

Sie sind nicht für alle sichtbar, sondern können per Tausch mit eigenen Insiderorten, die sich außerhalb der eigenen Komfortzone befinden, angeeignet werden.. Jeder Nutzer kann

Aus diesen unendlich vielen Dingen, welche miteinander getauscht werden können, bildete sich dann auch unser Swap Meet Logo, welches ein Unendlichkeitszeichen mit Pfeilen und