注意:
partA部分的fscanf()没有完全读取指令里的参数。
将ReadAndTest()改为:
result ReadAndTest(FILE *tracefile, entry_of_sets cache, uint64_t S, uint64_t E, uint64_t s, uint64_t b, _Bool verbose)
{
result Result = {0, 0, 0};
char ch;
uint64_t address;
int size;
/*fscanf()的使用*///这个地方需要改一下,读取标点和后一个数字,回去看看fscanf
while((fscanf(tracefile, " %c %lx,%d ", &ch, &address,&size)) >0 ) /* read instruction and address from tracefile and ignore the size */
/* address is represented by hexadecimal, use %lx instead of %lu */
{
if (ch == 'I') /*取指令的操作,忽视它*/
{
continue;
}
else
{
uint64_t set_index_mask = (1 << s) - 1;
uint64_t set_index = (address >> b) & set_index_mask;
uint64_t tag = (address >> b) >> s;
entry_of_lines search_line = cache[set_index];
/* 命令是加载/保存,我们就进入HitMissEviction一次判断其是否hit或者miss以及是否发生替换*/
if (ch == 'L' || ch == 'S')
{
if (verbose)
printf("%c %lx,%d ", ch, address,size);
/*
我们在ReadAndTest里通过一些位运算找到对应的set(即entry_of_lines),
然后以此作为参数调用HitMissEviction 判断到底是miss(有没有eviction)还是hit。
*/
Result = HitMissEviction(search_line, Result, E, tag, verbose);
}
else if (ch == 'M')
/*如果是修改就相当于一次”L“和一次“S”,需要进入HitMissEviction两次,
其结果可能为两次hit,也可能为:第一次,不明中(+一次退出),第二次命中(必须命中)*/
{
if (verbose)
printf("%c %lx,%d ", ch, address,size);
/*第一次加载,命中/不命中(+退出)*/
Result = HitMissEviction(search_line, Result, E, tag, verbose);
/*保存,必须命中*/
Result = HitMissEviction(search_line, Result, E, tag, verbose);
}
else
{
continue;
}
}
}
return Result;
}