bricoleur commit

This commit is contained in:
peteraa 2019-10-28 15:35:34 +01:00
parent ddec1ad315
commit e8322e2e5c
2 changed files with 15 additions and 57 deletions

View file

@ -164,54 +164,7 @@ object TestRunner {
helper(events, initState) helper(events, initState)
} }
def nBitPredictor(events: List[BranchEvent]): Int = {
case class nBitPredictor(
values : List[Int],
predictionRules : List[Boolean],
transitionRules : Int => Boolean => Int,
){
val slots = values.size
def predict(pc: Int): Boolean = predictionRules(values(pc.getTag(slots)))
def update(pc: Int, taken: Boolean): nBitPredictor = {
val current = values(pc.getTag(slots))
copy(values = values.updated(pc.getTag(slots), transitionRules(current)(taken)))
}
}
val initPredictor = nBitPredictor(
List.fill(4)(0),
List(
false,
false,
true,
true,
),
r => r match {
case 0 => taken => if(taken) 1 else 0
case 1 => taken => if(taken) 3 else 0
case 2 => taken => if(taken) 3 else 0
case 3 => taken => if(taken) 3 else 2
}
)
events.foldLeft((0, initPredictor)){ case(((acc, bp), event)) => event match {
case Taken(pc, _) if bp.predict(pc) => (acc, bp.update(pc, true))
case Taken(pc, _) => (acc + 1, bp.update(pc, false))
case NotTaken(pc) if !bp.predict(pc) => (acc, bp.update(pc, false))
case NotTaken(pc) => (acc + 1, bp.update(pc, true))
}}._1
}
say(OneBitInfiniteSlots(events)) say(OneBitInfiniteSlots(events))
say(nBitPredictor(events))
} }
true true

View file

@ -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 Taken(from: Int, to: Int) extends BranchEvent
case class NotTaken(addr: 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(from, to) :: t if( predictionTable(from)) => helper(t, predictionTable)
case Taken(addr) :: t if(!predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, true)) 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)) => 1 + helper(t, predictionTable.updated(addr, false))
case NotTaken(addr) :: t if( predictionTable(addr)) => helper(t, predictionTable) case NotTaken(addr) :: t if( predictionTable(addr)) => helper(t, predictionTable)
case _ => 0 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