also, nach einer neuen Tasche hatte ich einen Schlüssel bei meiner Mutter vergessen, das hat das ganze verzögert. Ich mache jetzt einen neuen Aufgabentyp.
Jetzt mache ich zu den üblichen Aufgaben, erst mal relativ übliche Aufgaben, die gehen so, dass ich die Datenabhängigkeiten erkennen muss, mit einer Folge von R-Typ Befehlen mit relativ ähnlichen registern, aber bewusst erzeugten Abhängigkeiten, dann mache ich das ganze bei mehrfädigen Prozessoren und 1 und 2 Bit Prädiktoren
aber, was ich auch mache ist eine ganze folge von Assembler Befehlen erzeugen mit zufälligen Registern. Dabei müssen alle Bits eingetragen werden, inklusive dem Datenpfad
Also, das geht zum Beispiel so. Ein R-Typ Befehl hat drei Register, 2 Quellregister rs, rt und ein Zielregister rd. Danebei den Opcode.
Ich muss für add erst mal den Opcode Bit 31 bis Bit 26 hinschreiben, dieser geht ins Befehlregister. Aber zum Beispiel der ADD Befehl erzeugt Binärcode für den Befehlsdekoder und das Funktionsregister für die ALU
Daneben werden vom Befehlsdekoder - Bits erzeugt, wie MemToReg, RegDst, RegWrite - jedes der Bits soll angezeigt werden, was auch nötig ist für den Datenpfad - weil die MUX entsprechend gestellt werden, aber auch der Datenpfad selber soll rein
Also, fange ich an mit den Aufgaben.
Danach mache ich auch die üblichen Aufgaben weiter - und das ganze muss auf meine Homepage
Für die Aufgabe mit der Datenabhängigkeit brauche ich vor allem R-Typ Befehle, egal ob diese sich auf CPUs mit einfacher Pipeline, oder zwei ALU's bezieht
Es gibt die echte Datenabhängigkeit, die Ausgabeabhängigkeit und die Gegenabhängigkeit. Es müssen dann entsprechend die Register verwendet werden, damit diese zustande kommen. Damit es kein Zufall ist, kann ich im C-Programm die einzelnen Abhängigkeiten jeweils definieren und dann per Zufall eine von ihnen erzeugen. Die Register werden dann durch Zufall gewählt, müssen aber entsprechend der Datenabhängigkeit wieder auftauchen.
Ebenso wird der Zufall sein, ob die Datenabhängigkeit, zum Beispiel die echte, 1 oder 2 Befehle nach dem ursprung beginnt.
Eine Ausgabeabhängigkeit spielt keine Rolle? Doch!
Eine Ausgabeabhängigkeit würde zunächst nur eine Rolle spielen, wenn wir Befehle unterschiedlicher Anzahl von Taktzyklen benutzen?
Macht nichts, bei einer echten Datenabhängigkeit lässt sich bezogen auf die Aufgabe, die Pipeline anhalten. Hier macht es einen Sinn an zu geben, die Pipeline an zu halten
Aber ohne die Pipeline an zu halten, kann man die Ausgabeabhängigkeit trotzdem erkennen.
Es macht aber unter einem Umstand sinn, auch, wenn die echte Datenabhängigkeit so oder so entfernt werden muss. Folgt auf eine Ausgabeabhängigkeit eine echte Datenabhängigkeit könnte ohne es zu wollen, die Ausgabeabhängigkeit sich auf ersteren Befehl beziehen
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ADD_STR "add" #define MULT_STR "mult" #define REG_STR "$r" #define ADD_FREQ 4 #define MULT_FREQ 1 #define REG_N 32 #define CLK_DIFF_MAX 3 int line = 1; int reg_rnd (void) { return rand () % 32; } void print_opstr (char *op, int rd, int rs, int rt) { printf ("%4i.\t%s %s%i, %s%i, %s%i\n", line++, op, REG_STR, rd, REG_STR, rs, REG_STR, rt); return; } void raw (int rd, int rs, int rt); void war (int rd, int rs, int rt); void waw (int rd, int rs, int rt); void no (int rd, int rs, int rt); void raw (int rd, int rs, int rt) { int _rs; int _rt; int _rd; int i; int clk = rand () % CLK_DIFF_MAX; if (rand () % 2) _rs = rs; else _rs = rand () % REG_N; if (rand () % 2) _rt = rt; else _rt = rand () % REG_N; if (rand () % 2) _rd = rs; else _rd = rand () % REG_N; print_opstr (ADD_STR, _rd, _rs, _rt); for (i = 0; i < clk; i++) print_opstr (ADD_STR, rand () % REG_N, rand () % REG_N, rand () % REG_N); if (rand () % 2) print_opstr (ADD_STR, rand () % REG_N, _rd, rand () % REG_N); else print_opstr (ADD_STR, rand () % REG_N, rand () % REG_N, _rd); if ((rand () % 6) != 0) { if (rand () % 4 == 3) raw (_rd, _rs, _rt); else if (rand () % 3 == 2) raw (_rd, _rs, _rt); else if (rand () % 3 == 1) war (_rd, _rs, _rt); else if (rand () % 3 == 0) no (_rd, _rs, _rt); } return; } void war (int rd, int rs, int rt) { int _rs; int _rt; int _rd; int i; int clk = rand () % CLK_DIFF_MAX; if (rand () % 2) _rs = rs; else _rs = rand () % REG_N; if (rand () % 2) _rt = rt; else _rt = rand () % REG_N; if (rand () % 2) _rd = rs; else _rd = rand () % REG_N; print_opstr (ADD_STR, _rd, _rs, _rt); for (i = 0; i < clk; i++) print_opstr (ADD_STR, rand () % REG_N, rand () % REG_N, rand () % REG_N); if (rand () % 2) print_opstr (ADD_STR, _rs, rand () % REG_N, rand () % REG_N); else print_opstr (ADD_STR, _rt, rand () % REG_N, rand () % REG_N); if ((rand () % 6) != 0) { if (rand () % 4 == 3) raw (_rd, _rs, _rt); else if (rand () % 3 == 2) raw (_rd, _rs, _rt); else if (rand () % 3 == 1) war (_rd, _rs, _rt); else if (rand () % 3 == 0) no (_rd, _rs, _rt); } return; } void waw (int rd, int rs, int rt) { int _rs; int _rt; int _rd; int i; int clk = rand () % CLK_DIFF_MAX; if (rand () % 2) _rs = rs; else _rs = rand () % REG_N; if (rand () % 2) _rt = rt; else _rt = rand () % REG_N; if (rand () % 2) _rd = rs; else _rd = rand () % REG_N; print_opstr (ADD_STR, _rd, _rs, _rt); for (i = 0; i < clk; i++) print_opstr (ADD_STR, rand () % REG_N, rand () % REG_N, rand () % REG_N); print_opstr (ADD_STR, _rd, rand () % REG_N, rand () % REG_N); if ((rand () % 6) != 0) { if (rand () % 4 == 3) raw (_rd, _rs, _rt); else if (rand () % 3 == 2) raw (_rd, _rs, _rt); else if (rand () % 3 == 1) war (_rd, _rs, _rt); else if (rand () % 3 == 0) no (_rd, _rs, _rt); } return; } void no (int rd, int rs, int rt) { int _rs; int _rt; int _rd; _rs = rand () % REG_N; _rt = rand () % REG_N; _rd = rand () % REG_N; print_opstr (ADD_STR, _rd, _rs, _rt); if ((rand () % 6) != 0) { if (rand () % 4 == 3) raw (_rd, _rs, _rt); else if (rand () % 3 == 2) raw (_rd, _rs, _rt); else if (rand () % 3 == 1) war (_rd, _rs, _rt); else if (rand () % 3 == 0) no (_rd, _rs, _rt); } return; } int main (void) { time_t t; srand ((unsigned)time (&t)); no (0, 1, 2); return 0; }
Ausgabe:
1. add $r7, $r14, $r11 2. add $r14, $r14, $r24 3. add $r24, $r18, $r20 4. add $r5, $r10, $r14 5. add $r14, $r27, $r24 6. add $r15, $r22, $r21 7. add $r11, $r13, $r2 8. add $r22, $r14, $r27 9. add $r27, $r15, $r31 10. add $r31, $r13, $r23 11. add $r27, $r18, $r13