-v: Optional verbose flag that displays trace info
-s <s>: Number of set index bits ($ S = 2^{s} $ is the number of sets)
-E <E>: Associativity (number of lines per set)
-b <b>: Number of block bits ($ B = 2^{b} $ is the block size)
-t <tracefile>: Name of the valgrind trace to replay
所以在 csim.c 里也可以写个打印帮助的函数
1 2 3 4 5 6 7
voidprintUsage(){ printf("Usage: ./csim [-h] [-v] -s <s> -E <E> -b <b> -t <tracefile>\n"); printf("-s: number of set index(2^s sets)\n"); printf("-E: number of lines per set\n"); printf("-b: number of block offset bits\n"); printf("-t: trace file name\n"); }
参考书中对cache的描述,需要些用结构体定义出cache的一些属性
1 2 3 4 5 6 7 8 9 10 11 12
typedefstruct{ int s;//2^s sets int S;//S=2^s int b;//2^b per block int B;//B=2^b int E;//number of lines per set //number to track the solution int hitNum; int missNum; int evictionNum; int verbosity; } cacheProperty;
intfindIndex(cacheSet set, cacheProperty property){ int i = 0; for(i = 0; i<property.E; i++){ if(set.lines[i].valid == 0){ return i; } } //shouldn't get a -1 anyway, method only called when there is granted space return-1; }
intfindEvict(cacheSet set, cacheProperty property){ intmin = set.lines[0].usedCounter; int i = 0; int index = 0; for(i = 0; i < property.E ; i++){ if(min>set.lines[i].usedCounter){ index = i; min = set.lines[i].usedCounter; } } return index; }
intfindMax(cacheSet set, cacheProperty property){ intmax = set.lines[0].usedCounter; int i = 0; int index = 0; for(i = 0; i < property.E ; i++){ if(set.lines[i].usedCounter>max){ index = i; max = set.lines[i].usedCounter; } } return index; }
cacheProperty simulate(cache currentCache,cacheProperty property, unsignedlonglong address){ //compute the size of the tag, 64 bit system int tagSize = 64-(property.b + property.s); unsignedlonglong tag = address >> (property.s + property.b); //use the tagSize to compute for the set index unsignedlonglong temp = address << (tagSize); unsignedlonglong setIndex = temp >> (tagSize + property.b); cacheSet set = currentCache.sets[setIndex]; //loop through lines in the set int i = 0; int hit = 0; for (i = 0; i<property.E; i++){ setLine currentLine = set.lines[i]; //check if there is a hit if(checkHit(currentLine, tag) == 1){ //if hit, update the staffs in the property property.hitNum+=1; intmax = 0; hit = 1; max = findMax(set, property); currentCache.sets[setIndex].lines[i].usedCounter = currentCache.sets[setIndex].lines[max].usedCounter+1; } } if(hit == 0 && checkFull(set, property) == 1){ //if not full then it is a miss, update the staffs in the property&set property.missNum+=1; int index = 0; index = findIndex(set, property); set.lines[index].tag = tag; set.lines[index].valid = 1; intmax = 0; max = findMax(set, property); currentCache.sets[setIndex].lines[index].usedCounter = currentCache.sets[setIndex].lines[max].usedCounter+1; }elseif(hit == 0){ //evict, update the staffs in the property&set property.missNum+=1; property.evictionNum+=1; int evictIndex = 0; //find the evict line evictIndex = findEvict(set, property); set.lines[evictIndex].tag = tag; intmax = 0; max = findMax(set, property); currentCache.sets[setIndex].lines[evictIndex].usedCounter = currentCache.sets[setIndex].lines[max].usedCounter+1; } return property; }
当然最后需要些一个主函数来调用测试接口。这里关于trace文件。每一条对内存访问的记录格式是 [空格]操作符 地址,大小,以 I 开头的是载入指令的记录,不算在内存访问中。