csapp 실험 캐 시 랩: 캐 시 메모리 이해
http://csapp.cs.cmu.edu/3e/cachelab.pdf
Part A: Writing a Cache Simulator
이곳 의 LRU 는 기 존 수업 에서 배 운 것 과 달리 먼저 주소 에 대해 해시 연산 을 하고 LRU 를 한다.E = 1 이면 LRU 가 아니다.정말 데 이 터 를 저장 할 필요 가 없습니다. hit, miss, eviction 횟수 만 계산 하면 됩 니 다.
#include
#include
#include
#include
#include
#include "cachelab.h"
#include
int S, E, B;
int hit = 0, miss = 0, eviction = 0;//
/*
* valid cacheLine ,addr ,time , 1
*/
typedef struct {
int valid;
long addr;
int time;
} cacheLine;
cacheLine *cache;
/*
* 1 hit,2 miss,4 eviction, 6 miss eviction
* , L,M,S。
* L S , B ( cache ), ,
*( 、 、 time)
* , index time。
* , time cacheLine。
*/
int readCacheLine(cacheLine *cache, char type, long addr);
void printHelp() {
printf("Usage: ./csim-wrc [-hv] -s -E -b -t
"
"• -h: Optional help flag that prints usage info
"
"• -v: Optional verbose flag that displays trace info
"
"• -s : Number of set index bits (S = 2^s is the number of sets)
"
"• -E : Associativity (number of lines per set)
"
"• -b : Number of block bits (B = 2^b is the block size)
"
"• -t : Name of the valgrind trace to replay
" );
}
/*
* 0
* 1
* 2
* 3
*/
int main(int argc, char *argv[]) {
opterr = 0;
int verboseFlag = 0;
int oc;
int error = 0;
int in = 0;
char *filePath = NULL;
while ((error == 0) && ((oc = getopt(argc, argv, "s:E:b:t:hv")) != -1)) {
in = 1;
switch (oc) {
case 's':
S = (int) pow(2, atoi(optarg));
break;
case 'E':
E = atoi(optarg);
break;
case 'b':
B = (int) pow(2, atoi(optarg));
break;
case 't':
filePath = optarg;
break;
case 'v':
verboseFlag = 1;
break;
case 'h':
case '?':
default:
error = 1;
printHelp();
break;
}
}
//
if (in == 0 && oc == -1)
printHelp();
if (error == 0) {
FILE *file = fopen(filePath, "r");
if (file == NULL) {
printf(" ");
return 3;
}
cache = (cacheLine *) malloc(S * E * sizeof(cacheLine));
if (cache == NULL) {
printf(" ");
return 2;
}
memset(cache, 0, S * E * sizeof(cacheLine));
char type;
int size;
long addr;
while (!feof(file)) {
int tr = fscanf(file, " %c %lx,%x", &type, &addr, &size);
if (tr != 3)
continue;
if (type != 'I') {
int rclResult = readCacheLine(cache, type, addr);
char *temp1 = NULL;
switch (rclResult) {
case 1:
hit++;
temp1 = "hit";
if (type == 'M')
hit++;
break;
case 2:
miss++;
temp1 = "miss";
break;
case 3:
miss++;
hit++;
temp1 = "miss";
break;
case 6:
miss++;
eviction++;
temp1 = "miss";
break;
case 7:
default:
miss++;
eviction++;
hit++;
temp1 = "miss";
break;
}
if (verboseFlag) {
printf("%c %lx,%x %s", type, addr, size, temp1);
if (rclResult == 6) {
printf(" eviction");
} else if (rclResult == 3) {
printf(" hit");
} else if (rclResult == 7) {
printf(" eviction hit");
} else if (rclResult == 1 && type == 'M') {
printf(" hit");
}
printf("
");
}
}
}
free(cache);
cache = NULL;
printSummary(hit, miss, eviction);
}
// printSummary(0, 0, 0);
return error;
}
int readCacheLine(cacheLine *cache, char type, long addr) {
int result = 0;
int sIndex = (int) ((addr / B) % S);
int eIndex = 0, minTime = INT_MAX, maxTime = -1, exist = 0, insert = 0;
for (int i = 0; i < E; ++i) {
cacheLine *ptr = (cache + sIndex * E + i);
if (insert == 0 && result == 0) {
if (ptr->valid != 1) {
ptr->valid = 1;
ptr->addr = addr;
insert = 1;
exist = 0;
result = 2;
eIndex = i;
if (type == 'M')
result = 3;
// break,
} else {
// addr , , time
if ((ptr->addr / B) == (addr / B)) {
exist = 1;
eIndex = i;
result = 1;
}
if (minTime > ptr->time) {
minTime = ptr->time;
if (exist == 0)
eIndex = i;
}
}
}
if (ptr->time > maxTime)
maxTime = ptr->time;
}
cacheLine *ptr = (cache + sIndex * E + eIndex);
//
if (insert == 0) {
if (exist == 0) {
ptr->addr = addr;
result = 6;
if (type == 'M')
result = 7;
}
}
ptr->time = maxTime + 1;
return result;
}
traces 디 렉 터 리 를 통 해 제 시 된 용례 테스트
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로그'메타프로그램 루비 버전 2'3장 읽기동적 방법 Object#send 호출 방법은 약간 메모와 Object#send obj.send(:my_method, 3) Object#send를 사용하면 어떤 방법으로든 호출할 수 있습니다. privete 방법을 호...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.