|
|
@@ -95,7 +95,7 @@ |
|
|
#+end_src |
|
|
#+end_src |
|
|
|
|
|
|
|
|
* Question 3 - Branch prediction |
|
|
* Question 3 - Branch prediction |
|
|
Consider a 2 bit branch predictor with only 4 slots for a 32 bit architecture, where the decision to |
|
|
|
|
|
|
|
|
Consider a 2 bit branch predictor with only 4 slots for a 32 bit architecture (without BTB), where the decision to |
|
|
take a branch or not is decided in accordance to the following table: |
|
|
take a branch or not is decided in accordance to the following table: |
|
|
#+begin_src text |
|
|
#+begin_src text |
|
|
state || predict taken || next state if taken || next state if not taken || |
|
|
state || predict taken || next state if taken || next state if not taken || |
|
|
@@ -137,8 +137,8 @@ |
|
|
|
|
|
|
|
|
#+BEGIN_SRC scala |
|
|
#+BEGIN_SRC scala |
|
|
sealed trait BranchEvent |
|
|
sealed trait BranchEvent |
|
|
case class Taken(addr: Int) extends BranchEvent |
|
|
|
|
|
case class NotTaken(addr: Int) extends BranchEvent |
|
|
|
|
|
|
|
|
case class Taken(from: Int, to: Int) extends BranchEvent |
|
|
|
|
|
case class NotTaken(at: Int) extends BranchEvent |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def profile(events: List[BranchEvent]): Int = ??? |
|
|
def profile(events: List[BranchEvent]): Int = ??? |
|
|
@@ -170,11 +170,11 @@ |
|
|
// `case Constructor(arg1, arg2) :: t => if(p(arg1, arg2))` |
|
|
// `case Constructor(arg1, arg2) :: t => if(p(arg1, arg2))` |
|
|
// means we want to match a list whose first element is of type Constructor while satisfying some predicate p, |
|
|
// means we want to match a list whose first element is of type Constructor while satisfying some predicate p, |
|
|
// called an if guard. |
|
|
// called an if guard. |
|
|
case Taken(addr) :: t if( predictionTable(addr)) => helper(t, predictionTable) |
|
|
|
|
|
case Taken(addr) :: t if(!predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, true)) |
|
|
|
|
|
case NotTaken(addr) :: t if(!predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, false)) |
|
|
|
|
|
case NotTaken(addr) :: t if( predictionTable(addr)) => helper(t, predictionTable) |
|
|
|
|
|
case _ => 0 |
|
|
|
|
|
|
|
|
case Taken(from, to) :: t if( predictionTable(from)) => helper(t, predictionTable) |
|
|
|
|
|
case Taken(from, to) :: t if(!predictionTable(from)) => 1 + helper(t, predictionTable.updated(from, true)) |
|
|
|
|
|
case NotTaken(addr) :: t if(!predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, false)) |
|
|
|
|
|
case NotTaken(addr) :: t if( predictionTable(addr)) => helper(t, predictionTable) |
|
|
|
|
|
case _ => 0 |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -191,14 +191,19 @@ |
|
|
** Your task |
|
|
** Your task |
|
|
Your job is to implement a test that checks how many misses occur for a 2 bit branch predictor with 8 slots. |
|
|
Your job is to implement a test that checks how many misses occur for a 2 bit branch predictor with 8 slots. |
|
|
The rule table is the same as in question 3. |
|
|
The rule table is the same as in question 3. |
|
|
For simplicitys sake, assume that every value in the table is initialized to 00. |
|
|
|
|
|
|
|
|
The predictor does not use a branch target buffer (BTB), which means that the address will always be decoded in |
|
|
|
|
|
the ID stage. |
|
|
|
|
|
For you this means you do not need to keep track of branch targets, simplifying your simulation quite a bit. |
|
|
|
|
|
(If not you would need to add logic for when BTB value does not match actual value) |
|
|
|
|
|
|
|
|
|
|
|
For simplicity's sake, assume that every value in the table is initialized to 00. |
|
|
|
|
|
|
|
|
For this task it is necessary to use something more sophisticated than ~Map[(Int, Boolean)]~ to represent |
|
|
For this task it is necessary to use something more sophisticated than ~Map[(Int, Boolean)]~ to represent |
|
|
your branch predictor model. |
|
|
your branch predictor model. |
|
|
|
|
|
|
|
|
The skeleton code is located in ~testRunner.scala~ and can be run using testOnly FiveStage.ProfileTest. |
|
|
The skeleton code is located in ~testRunner.scala~ and can be run using testOnly FiveStage.ProfileTest. |
|
|
|
|
|
|
|
|
With a 2 bit 4 slot scheme, how many misses will you incur? |
|
|
|
|
|
|
|
|
With a 2 bit 8 slot scheme, how many mispredicts will happen? |
|
|
Answer with a number. |
|
|
Answer with a number. |
|
|
|
|
|
|
|
|
* Question 5 - Cache profiling |
|
|
* Question 5 - Cache profiling |
|
|
|