Ü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 = RiRj 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 = Rin 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)?