| @@ -165,7 +165,48 @@ object TestRunner { | |||
| helper(events, initState) | |||
| } | |||
| /** | |||
| * This is profiler for a 2-bit 8-slot branch predictor. | |||
| */ | |||
| def TwoBitEightSlots(events: List[BranchEvent]): Int = { | |||
| // Uncomment to take a look at the event log | |||
| // say(events.mkString("\n","\n","\n")) | |||
| // Helper inspects the next element of the event list. If the event is a mispredict the prediction table is updated | |||
| // to reflect this. | |||
| // As long as there are remaining events the helper calls itself recursively on the remainder | |||
| def helper(events: List[BranchEvent], predictionTable: Map[Int, Int]): Int = { | |||
| events match { | |||
| case Taken(from, to) :: t if(predictionTable(hash(from)) == 0) => 1 + helper(t, predictionTable.updated(hash(from), 1)) | |||
| case Taken(from, to) :: t if(predictionTable(hash(from)) == 1) => 1 + helper(t, predictionTable.updated(hash(from), 2)) | |||
| case Taken(from, to) :: t if(predictionTable(hash(from)) == 2) => helper(t, predictionTable.updated(hash(from), 3)) | |||
| case Taken(from, to) :: t if(predictionTable(hash(from)) == 3) => helper(t, predictionTable) | |||
| case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 0) => helper(t, predictionTable) | |||
| case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 1) => helper(t, predictionTable.updated(hash(addr), 0)) | |||
| case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 2) => 1 + helper(t, predictionTable.updated(hash(addr), 1)) | |||
| case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 3) => 1 + helper(t, predictionTable.updated(hash(addr), 2)) | |||
| case Nil => 0 | |||
| } | |||
| } | |||
| def hash(addr: Int): Int = addr.getTag(8) | |||
| def initState = Map( | |||
| 0 -> 0, | |||
| 1 -> 0, | |||
| 2 -> 0, | |||
| 3 -> 0, | |||
| 4 -> 0, | |||
| 5 -> 0, | |||
| 6 -> 0, | |||
| 7 -> 0, | |||
| ) | |||
| helper(events, initState) | |||
| } | |||
| say(OneBitInfiniteSlots(events)) | |||
| say(TwoBitEightSlots(events)) | |||
| } | |||
| @@ -190,9 +231,66 @@ object TestRunner { | |||
| case MemRead(x,_) => Read(x.value) | |||
| } | |||
| // Your cache here | |||
| case class CacheEntry(var tag: Int, var lru: Boolean) | |||
| type Cache = Map[Int, List[CacheEntry]] | |||
| /** | |||
| * This is profiler for a 2-way associative 4 word cache | |||
| */ | |||
| def TwoWayFourWord(events: List[MemoryEvent]): Int = { | |||
| def helper(events: List[MemoryEvent], cache: Cache): Int = { | |||
| events match { | |||
| case Write(addr) :: t => helper(t, cache) | |||
| case Read(addr) :: t if( inCache(addr, cache)) => 1+helper(t, useCache(addr, cache)) | |||
| case Read(addr) :: t if(!inCache(addr, cache)) => helper(t, addToCache(addr, cache)) | |||
| case Nil => say(cache); 0 | |||
| } | |||
| } | |||
| def getIndex(addr: Int): Int = addr.getTag(2) | |||
| def getTag(addr: Int): Int = addr >>> 3 | |||
| def inCache(addr: Int, cache: Cache): Boolean = { | |||
| cache(getIndex(addr))(0).tag == getTag(addr) || cache(getIndex(addr))(1).tag == getTag(addr) | |||
| } | |||
| def useCache(addr: Int, cache: Cache): Cache = { | |||
| if (cache(getIndex(addr))(0).tag == getTag(addr)) { | |||
| cache(getIndex(addr))(0).lru = false | |||
| cache(getIndex(addr))(1).lru = true | |||
| } else { | |||
| cache(getIndex(addr))(1).lru = false | |||
| cache(getIndex(addr))(0).lru = true | |||
| } | |||
| cache | |||
| } | |||
| def addToCache(addr: Int, cache: Cache): Cache = { | |||
| if (cache(getIndex(addr))(0).lru) { | |||
| cache(getIndex(addr))(0).tag = getTag(addr) | |||
| cache(getIndex(addr))(0).lru = false | |||
| cache(getIndex(addr))(1).lru = true | |||
| } else { | |||
| cache(getIndex(addr))(1).tag = getTag(addr) | |||
| cache(getIndex(addr))(1).lru = false | |||
| cache(getIndex(addr))(0).lru = true | |||
| } | |||
| cache | |||
| } | |||
| def initState = Map( | |||
| 0 -> List(CacheEntry(-1, true), CacheEntry(-1, true)), | |||
| 1 -> List(CacheEntry(-1, true), CacheEntry(-1, true)), | |||
| ) | |||
| helper(events, initState) | |||
| } | |||
| say(TwoWayFourWord(events)) | |||
| } | |||
| true | |||
| } | |||
| } | |||