Das folgende Programm führt eine Addition auf den Komponenten

Werbung
Übungsblatt 11 – Übung Grundlagen Rechnerarchitektur, SS 2011
Ausgabe: 17.7.2011
1. Gegeben sei die nachfolgende Befehlsfolge. Diese soll auf einer VLIW-Architektur
umgesetzt werden. Geben Sie den Datenabhängigkeitsgraph für die Befehlsfolge
an und erstellen Sie entsprechend die VLIW-Befehlswörter bestehend aus je 3 Befehlen. Fügen Sie NOP-Operationen in ein VLIW-Befehlswort ein, wenn dieses
nicht komplett mit 3 der angegebenen Befehle gefüllt werden kann. Es kann davon
ausgegangen werden, dass es bzgl. der Befehlsgruppierung keine Einschränkungen durch die zu Grunde liegende VLIW-Architektur gibt.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
R6 Speicher
R1=0
R1=R1+R2
Speicher R1
R2=R3
R5=R1+R6
R2=R2-1
R3=R3+5
R4=R5+R6
R2=R2+R1
Speicher R4
2. Eine Befehlssequenz der Form
op1
op2
op3
kann leicht in einen äquivalenten VLIW-Befehl umgeformt werden, wenn die Befehle op1, op2 und op3 keinerlei Abhängigkeiten untereinander aufweisen und es
sich um keine Sprungbefehle handelt. Im Falle einer CPU mit drei nebenläufig
betreibbaren Rechenwerken sieht das zugehörige lange Befehlswort wie folgt aus:
Adresse VLIWBefehl:
1:
Befehl für
1. Rechenwerk
op1
Befehl für
2. Rechenwerk
op2
Befehl für
3. Rechenwerk
op3
Im Folgenden wird angenommen, dass jedes der drei Rechenwerke einen zugeordneten Registersatz R1, H1, R2, H2, bzw. R3, H3 besitze. Der Prozessor sei
als Load-Store-Architektur realisiert. Mit Hilfe des Befehls MOV feld[x] -> R (R
 {Ri, Hi; 1 <= i <= 3}) kann aus der Adresse feld[x] ein Wert in ein Register geladen werden. Der Befehl entspricht somit einem LOAD-Befehl. Der umgekehrte Weg, also ein STORE-Befehl, d.h. das Laden einer Speicherzelle mit
dem aktuellen Inhalt eines Registers, geschieht einfach über Vertauschen von
Speicher- und Registeradresse. Ferner existieren Zweiadressbefehle für das Addieren und das Multiplizieren mit folgender Syntax und Semantik.
ADD Ri, Rj -> Rz (Ri, Rj, Rz  {Ri, Hi; 1 <= i <= 3}); Rz = Ri+Rj
MUL Ri, Rj -> Rz (Ri, Rj, Rz  {Ri, Hi; 1 <= i <= 3}); Rz = RiRj
Alternativ kann eine der Registervariablen auch durch einen Immediate-Wert ersetzt werden.
ADD Ri, #n -> Rz (Ri, Rj, Rz  {Ri, Hi; 1 <= i <= 3}); Rz = Ri+n
MUL Ri, #n -> Rz (Ri, Rj, Rz  {Ri, Hi; 1 <= i <= 3}); Rz = Rin
Das untenstehende Programm führt eine Addition auf den Komponenten der Vektoren a und b durch. Das Ergebnis der Vektoraddition wird in den Vektor c geschrieben. Die Vektoren sind durch entprechende Felder vom Typ Integer a, b und
c gegeben.
#define N 9
int
a[N], b[N], c[N] ;
for (int lv = 0; lv < N; lv++)
c[lv] = a[lv] + b[lv] ;
a) Wie lässt sich die for-Schleife umformen, so dass das obige Schema für die
Transformation in einen äquivalenten VLIW-Befehl anwendbar wird?
b) Wie sieht das zugehörige VLIW-Programm in Pseudocode-Darstellung aus?
Zur Steuerung des Kontrollflusses darf ferner eine zusätzliche globale Variable
lv sowie eine Anweisung der Form if (bedingung) then goto label
benutzt werden.
In vielen Anwendungen aus der digitalen Signalverarbeitung, z.B. bei der JPEGoder MPEG-Kodierung, kommen häufig Berechnungsvorschriften der folgenden
Form vor:
#define N 9
int
a[N][N], b[N][N], c[N][N], h ;
for (int lv1 = 0; lv1 < N; lv1++)
for (int lv = 0; lv < N; lv++) {
h = a[lv1][lv] * b[lv][lv1] ;
c[lv1][lv] = c[lv1][lv] + h ;
}
// op1
// op2
c) Warum kann das obige Schema für ein Übertragen in ein paralleles VLIWProgramm für die innere Schleife nicht angewandt werden?
d) Wie kann das Hochsprachenprogramm leicht umgeformt werden, so dass wieder das obige Schema für die Übertragung in ein entsprechendes VLIWProgramm anwendbar ist?
e) Nun sollen die drei Rechenwerke über einen Multithreading-Ansatz ausgelastet
werden. Wie sieht ein entsprechendes Multithreading-Programm aus? Wie
lässt sich die innere Schleife im einfachsten Fall in drei unabhängige Threads
aufteilen?
f) Welcher Unterschied besteht zum semantisch äquivalenten VLIW-Programm?
g) Worin besteht grundsätzlich ein Nachteil von VLIW gegenüber Multithreading,
s. folgendes Beispiel. In diesem seien die Operatoren op1, op2 und op3 unabhängig.
int i ;
for (int lv = 0; lv < N; lv++)
op1 ;
i = lv % 2 ;
// % entspricht Modulo-Operation
switch (i) {
case 0: op2; break ;
case 1: op3; break ;
}
} ;
3. Was ist der Unterschied zwischen einem Quad-Core-Prozessor und einem DualCore-Prozessor mit Hyperthreading (SMT mit zwei Threads)?
Herunterladen