Просмотр исходного кода

Implement profiling tests

sindre-ex2
Sindre Stephansen 6 лет назад
Родитель
Сommit
360ccd9269
1 измененных файлов: 99 добавлений и 1 удалений
  1. +99
    -1
      src/test/scala/RISCV/testRunner.scala

+ 99
- 1
src/test/scala/RISCV/testRunner.scala Просмотреть файл

@@ -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
}
}

Загрузка…
Отмена
Сохранить