Scoreboard and Tomasulo

 

1. Parallel Computing

  Parallelism, playing a role as important as Memory Hierarchy, can be implemented in different levels in a computer architecture:

 

  What I want to talk about now is the Instruction-Level Parallelism (ILP), which can be implemented by pipelining with forwarding unit and hazard detection unit in MIPS32 architecture as we have learned in EI209. The issue at that time was to address three types of pipeline hazard: Data Hazard, Structural Hazard and Control Hazard.

  However, ILP can be advanced if we allow out-of-order execution of instructions so that data hazard stalls can be further reduced. This is what we call Dynamic Scheduling, which can address Name Dependences in a block of program. There are another two strategies called Dynamic Branch Prediction and Speculation, which can minimize control stalls.

  Now I will show you my demo programs of two ILP instances that make good use of Dynamic Scheduling: one is Scoreboard Algorithm in CDC6600, another is Tomasulo Algorithm in IBM360.

  Sample Input:

6
LD  F6 %34 R2
LD  F2 %45 R3
MULTD  F0 F2 F4
SUBD  F8 F6 F2
DIVD  F10 F0 F6
ADDD  F6 F8 F2

 

 

2. Scoreboard Algorithm

  See  wikipedia  for more information about this algorithm.

  1 import java.util.*;
  2 import java.io.*;
  3 Algorithm
  4 public class Scoreboard {
  5     private static class Inst {
  6         private String op;
  7         private int dest,src1,src2;
  8         private int stage;
  9         private int pos;
 10         
 11         public Inst() {
 12             // Interpret and Store Instructions
 13             op = in.next();
 14             String buf;
 15             buf = in.next();
 16             dest = Integer.parseInt(buf.substring(1))/2;
 17             buf = in.next();
 18             if (buf.charAt(0)!='%')
 19                 src1 = Integer.parseInt(buf.substring(1))/2;
 20             else
 21                 src1 = -1;
 22             buf = in.next();
 23             src2 = Integer.parseInt(buf.substring(1))/2;
 24             stage = 0;
 25             pos = -1;
 26         }
 27         public boolean ready() {
 28             switch (stage) {
 29             case 0:
 30                 return issueReady();
 31             case 1:
 32                 return readOpReady();
 33             case 2:
 34                 return execCompReady();
 35             case 3:
 36                 return wrtResReady();
 37             default:
 38                 return false;
 39             }
 40         }
 41         private boolean issueReady() {
 42             if (iss) {
 43                 // iss guarantees "in-order"
 44                 iss = false;
 45                 pos = -1;
 46                 srchFreeUnit();
 47                 // no structural hazard or WAW
 48                 return pos>=0 && res[dest]<0;
 49             } else
 50                 return false;
 51         }
 52         private void srchFreeUnit() {
 53             // Search for a Function Unit unoccupied
 54             if (op.equals("LD")||op.equals("SD")) {
 55                 if (!unit[0].busy)
 56                     pos = 0;
 57             } else if (op.equals("MULTD")) {
 58                 if (!unit[1].busy)
 59                     pos = 1;
 60                 else if (!unit[2].busy)
 61                     pos = 2;
 62             } else if (op.equals("ADDD")||op.equals("SUBD")) {
 63                 if (!unit[3].busy)
 64                     pos = 3;
 65             } else if (op.equals("DIVD")) {
 66                 if (!unit[4].busy)
 67                     pos = 4;
 68             }
 69         }
 70         private boolean readOpReady() {
 71             // no RAW data hazard
 72             return unit[pos].Rj && unit[pos].Rk;
 73         }
 74         private boolean execCompReady() {
 75             return --unit[pos].time==0;
 76         }
 77         private boolean wrtResReady() {
 78             for (int i=0;i<5;i++) {
 79                 // no WAR hazard
 80                 if (unit[i].Fj==dest&&unit[i].Rj)
 81                     return false;
 82                 if (unit[i].Fk==dest&&unit[i].Rk)
 83                     return false;
 84             }
 85             return true;
 86         }
 87         public boolean next() {
 88             // Show the action and do the bookkeeping
 89             switch(stage++) {
 90             case 0:
 91                 System.out.println("is issued");
 92                 issueBookkeep();
 93                 return false;
 94             case 1:
 95                 System.out.println("reads operands");
 96                 readOpBookkeep();
 97                 return false;
 98             case 2:
 99                 System.out.println("completes execution");
100                 return false;
101             case 3:
102                 System.out.println("writes result");
103                 wrtResBookkeep();
104                 return true;
105             default:
106                 return false;
107             }
108         }
109         private void issueBookkeep() {
110             unit[pos].busy = true;
111             unit[pos].op = op;
112             if (op.equals("SD")) {
113                 unit[pos].Fi = -1;
114                 unit[pos].Fj = dest;
115                 unit[pos].Fk = src2;
116             } else {
117                 unit[pos].Fi = dest;
118                 unit[pos].Fj = src1;
119                 unit[pos].Fk = src2;
120             }
121             if (src1>=0)
122                 unit[pos].Qj = res[src1];
123             else
124                 unit[pos].Qj = -1;
125             unit[pos].Qk = res[src2];
126             unit[pos].Rj = (unit[pos].Qj<0);
127             unit[pos].Rk = (unit[pos].Qk<0);
128             if (!op.equals("SD"))
129                 res[dest] = pos;
130         }
131         private void readOpBookkeep() {
132             // no more WAR hazard
133             unit[pos].Rj = false;
134             unit[pos].Rk = false;
135             if (pos==0)
136                 unit[pos].time = 1;
137             else if (pos<=2)
138                 unit[pos].time = 10;
139             else if (pos==3)
140                 unit[pos].time = 2;
141             else
142                 unit[pos].time = 40;
143         }
144         private void wrtResBookkeep() {
145             // no more RAW hazard
146             for (int i=0;i<5;i++) {
147                 if (unit[i].Qj==pos)
148                     unit[i].Rj = true;
149                 if (unit[i].Qk==pos)
150                     unit[i].Rk = true;
151             }
152             // no more structural hazard
153             unit[pos].busy = false;
154             // no more WAW hazard
155             if (!op.equals("SD"))
156                 res[dest] = -1;
157         }
158     }
159     private static class FU {
160         public int time;
161         public String name;
162         public boolean busy;
163         public String op;
164         public int Fi,Fj,Fk;
165         public int Qj,Qk;
166         public boolean Rj,Rk;
167         
168         public FU(String str) {
169             time = 0;
170             name = str;
171             busy = false;
172             op = null;
173             Fi=Fj=Fk = -1;
174             Qj=Qk = -1;
175             Rj=Rk = false;
176         }
177     }
178 
179     private static Scanner in;
180     private static boolean iss;
181     private static Inst[] inst;
182     private static FU[] unit;
183     private static int[] res;
184     
185     private static void init_all(int n) {
186         inst = new Inst[n];
187         unit = new FU[5];
188         unit[0] = new FU("Integer");
189         unit[1] = new FU("Mult1");
190         unit[2] = new FU("Mult2");
191         unit[3] = new FU("Add");
192         unit[4] = new FU("Divide");
193         res = new int[8];
194         for (int i=0;i<8;i++)
195             res[i] = -1;
196     }
197     public static void main(String[] args) throws IOException {
198         // read and buffer all the instructions:
199         in = new Scanner(new FileReader("CDC6600.in"));
200         int n = in.nextInt();
201         init_all(n);
202         for (int i=0;i<n;i++)
203             inst[i] = new Inst();
204         in.close();
205         // in-order issue, out-of-order execution:
206         int clk=0, over=0;
207         boolean flag[] = new boolean[n];
208         while (over<n) {
209             System.out.print(">> CLOCK CYCLE ");
210             System.out.println(++clk);
211             iss = true;
212             for (int i=0;i<n;i++)
213                 flag[i] = inst[i].ready();
214             for (int i=0;i<n;i++) {
215                 if (flag[i]){
216                     System.out.print("\tinst ");
217                     System.out.print((i+1)+" ");
218                     if (inst[i].next())
219                         over++;
220                 }
221             }
222         }
223     }
224 }

 

 

3. Tomasulo Algorithm

  See  wikipedia  for more information about this algorithm.

  1 import java.util.*;
  2 import java.io.*;
  3 
  4 public class Tomasulo {
  5     private static class Inst {
  6         private String op;
  7         private int dest,src1,src2;
  8         private int stage;
  9         private int pos;
 10         
 11         public Inst() {
 12             // Interpret and store instructions
 13             op = in.next();
 14             String buf;
 15             buf = in.next();
 16             dest = Integer.parseInt(buf.substring(1))/2;
 17             buf = in.next();
 18             if (buf.charAt(0)!='%')
 19                 src1 = Integer.parseInt(buf.substring(1))/2;
 20             else
 21                 src1 = -1;
 22             buf = in.next();
 23             src2 = Integer.parseInt(buf.substring(1))/2;
 24             stage = 0;
 25             pos = -1;
 26         }
 27         public boolean ready() {
 28             switch (stage) {
 29             case 0:
 30                 return issueReady();
 31             case 1:
 32                 return execReady();
 33             case 2:
 34                 return execCompReady();
 35             case 3:
 36                 return wrtResReady();
 37             default:
 38                 return false;
 39             }
 40         }
 41         private boolean issueReady() {
 42             if (iss) {
 43                 // iss guarantees in-order issue
 44                 iss = false;
 45                 pos = -1;
 46                 srchFreeUnit();
 47                 // no structural hazard
 48                 return pos>=0;
 49             } else
 50                 return false;
 51         }
 52         private void srchFreeUnit() {
 53             // Search for a Reservation Station unoccupied
 54             if (op.equals("ADDD")||op.equals("SUBD")) {
 55                 for (int i=0;i<=2;i++) {
 56                     if (!unit[i].busy) {
 57                         pos = i;
 58                         return;
 59                     }
 60                 }
 61             } else if (op.equals("MULTD")||op.equals("DIVD")) {
 62                 for (int i=3;i<=4;i++) {
 63                     if (!unit[i].busy) {
 64                         pos = i;
 65                         return;
 66                     }
 67                 }
 68             } else if (op.equals("LD")) {
 69                 for (int i=5;i<=10;i++) {
 70                     if (!unit[i].busy) {
 71                         pos = i;
 72                         return;
 73                     }
 74                 }
 75             } else if (op.equals("SD")) {
 76                 for (int i=11;i<=13;i++) {
 77                     if (!unit[i].busy) {
 78                         pos = i;
 79                         return;
 80                     }
 81                 }
 82             }
 83         }
 84         private boolean execReady() {
 85             // no RAW data hazard
 86             if (pos<=4)        // FP operations
 87                 return unit[pos].Qj<0 && unit[pos].Qk<0;
 88             else if (mem) {
 89                 // mem guarantees in-order load/store
 90                 mem = false;
 91                 return unit[pos].Qk<0;
 92             } else
 93                 return false;
 94         }
 95         private boolean execCompReady() {
 96             return --unit[pos].time==0;
 97         }
 98         private boolean wrtResReady() {
 99             if (op.equals("SD"))
100                  return unit[pos].Qj<0;
101             else if (cbd){
102                 // no CBD conflict
103                 cbd = false;
104                 return true;
105             } else
106                 return false;
107         }
108         public boolean next() {
109             // Show the action and do the bookkeeping
110             switch(stage++) {
111             case 0:
112                 System.out.println("is issued");
113                 issueBookkeep();
114                 return false;
115             case 1:
116                 System.out.println("starts to execute");
117                 execBookkeep();
118                 return false;
119             case 2:
120                 System.out.println("completes execution");
121                 return false;
122             case 3:
123                 System.out.println("writes result");
124                 wrtResBookkeep();
125                 return true;
126             default:
127                 return false;
128             }
129         }
130         private void issueBookkeep() {
131             unit[pos].busy = true;
132             unit[pos].op = op;
133             if (!op.equals("SD")) {
134                 if (src1>=0)
135                     unit[pos].Qj = res[src1];
136                 else
137                     unit[pos].Qj = -1;
138                 unit[pos].Qk = res[src2];
139                 res[dest] = pos;
140             } else {
141                 unit[pos].Qj = res[dest];
142                 unit[pos].Qk = res[src2];
143             }
144         }
145         private void execBookkeep() {
146             if (pos<=2)
147                 unit[pos].time = 2;
148             else if (op.equals("MULTD"))
149                 unit[pos].time = 10;
150             else if (op.equals("DIVD"))
151                 unit[pos].time = 40;
152             else
153                 unit[pos].time = 1;
154         }
155         private void wrtResBookkeep() {
156             if (!op.equals("SD")) {
157                 for (int i=0;i<8;i++) {
158                     if (res[i]==pos)
159                         res[i] = -1;
160                 }
161                 for (int i=0;i<14;i++) {
162                     if (unit[i].Qj==pos)
163                         unit[i].Qj = -1;
164                     if (unit[i].Qk==pos)
165                         unit[i].Qk = -1;
166                 }
167             }
168             unit[pos].busy = false;
169         }
170     }
171     private static class RS {
172         public int time;
173         public String name;
174         public boolean busy;
175         public String op;
176         public int Qj,Qk;
177         
178         public RS(String str) {
179             time = 0;
180             name = str;
181             busy = false;
182             op = null;
183             Qj=Qk = -1;
184         }
185     }
186     
187     private static Scanner in;
188     private static boolean iss,cbd,mem;
189     private static Inst[] inst;
190     private static RS[] unit;
191     private static int[] res;
192 
193     private static void init_all(int n) {
194         inst = new Inst[n];
195         unit = new RS[14];
196         for (int i=0;i<3;i++)
197             unit[i] = new RS("Add"+Integer.toString(i+1));
198         for (int i=0;i<2;i++)
199             unit[3+i] = new RS("Mult"+Integer.toString(i+1));
200         for (int i=0;i<6;i++)
201             unit[5+i] = new RS("Load"+Integer.toString(i+1));
202         for (int i=0;i<3;i++)
203             unit[11+i] = new RS("Store"+Integer.toString(i+1));
204         res = new int[8];
205         for (int i=0;i<8;i++)
206             res[i] = -1;
207     }
208     public static void main(String[] args) throws IOException {
209         // read and buffer all the instructions:
210         in = new Scanner(new FileReader("IBM360.in"));
211         int n = in.nextInt();
212         init_all(n);
213         for (int i=0;i<n;i++)
214             inst[i] = new Inst();
215         in.close();
216         // in-order issue, out-of-order execution:
217         int clk=0, over=0;
218         while (over<n) {
219             System.out.print(">> CLOCK CYCLE ");
220             System.out.println(++clk);
221             iss = cbd = mem = true;
222             for (int i=0;i<n;i++) {
223                 if (inst[i].ready()){
224                     System.out.print("\tinst ");
225                     System.out.print((i+1)+" ");
226                     if (inst[i].next())
227                         over++;
228                 }
229             }
230         }
231     }
232 }

 

 

References:

  1. Hennessy, John L., and David A. Patterson. Computer Architecture: A Quantitative Approach[M]. 北京:人民邮电出版社, 2013-01

 

posted on 2015-03-23 08:08  DevinZ  阅读(705)  评论(0编辑  收藏  举报

导航