| @@ -165,7 +165,48 @@ object TestRunner { | |||||
| helper(events, initState) | 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(OneBitInfiniteSlots(events)) | ||||
| say(TwoBitEightSlots(events)) | |||||
| } | } | ||||
| @@ -190,9 +231,66 @@ object TestRunner { | |||||
| case MemRead(x,_) => Read(x.value) | 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 | true | ||||
| } | } | ||||
| } | } | ||||