一、
实验步骤
在上次的实验中,我确立了实验的基本思路,本周将按照上周的思路,逐个实验函数并进行调试,最终组和到一起,完成整个实验。
正式开始实验,第一步先解决传入参数的问题,根据实验指导书的建议,选择使用getopt()函数来处理传入的参数。关于函数的具体使用方法,具体可以参照https://www.cnblogs.com/qingergege/p/5914218.html 这篇博客的内容。
首先解决如何传入参数的问题。
下面是代码。
输入 ./csim -v -s 3 -E 4 -b 33
-t traces/yi.trace进行调试。
发现有输出信息,证明上面的代码应该可以成功获取到参数。
接下来定义使用到的一些函数。
首先是声明cache的结构体。
Cache可以使用一个三阶的数组来存储。
使用宏定义#define uint long
unsigned int
#define FOR(i,a,b) for(int i=a;i<b;i++)
从别人的代码中学到了这个定义方式来简化for循环的写法,接下来的for循环都采用这种形式。
Struct cache{
unit s,E,b;
unit ***cache;
}cache;
数组的三维表示的含义如下:
我用xmind画了一张图,大概意思如图所示。
接下来是设置和获取s、E、b值的大小的常用get和set方法。
及对cache分配和释放空间的方法。
这一部分感觉不太会出问题,也不好测试,我是先在Devc上写好检查语法上的问题,等下和后面的方法一起测试。在函数之前加了注解说明该函数的作用。
3.获取LRU函数
接下来写获得最小LRU函数,具体的代码在网上有很多版本,我直接选择了一种实现方式。
看了一下,这个是使用暴力遍历的方式找lru最小的组,当然也可以使用递归的方式。
4.判断是否命中和置换方法
再接下来是判断是否命中的函数。主要根据标志位和有效位进行判断,如果有效位为1但是标志位不匹配,还要进行页调换,产生牺牲。
在这里先把三个数值,命中值,不命中值,和调换次数定义一下。分别用Hits,Misses和Evictions表示,初始值均为0.
返回值为-1说明没有命中。
接下来写发生不命中和冲突时要使用的调换方法。被调换的块通过lru算法找到。
5.从文件中读取参数并转换得到s、b、E值
接下来要对文件的内容进行读取,并从中解读中具体指令和地址相应的组和列以及标志位。使用fscanf函数对文件读取,每次读取一行。
文件中数据的格式如上图。因此读取数据的函数为
fscanf(Path,"%s%lx%c%lu",comand,&address,&Char,&block)
comand代表指令具体为‘I’’M’‘L’’S’中的任意一个。
Address为读取到的地址,char代表‘,’不用处理,block为块大小,需要保存起来。
接下来从地址中计算出组和行数,根据组选择,行标记的原则和上次实验中得到的s、E、b值的关系。
可以得到转化函数如下
Tag=address>>(_s+_b);
S=
(address >> _b) & ((1 << _s) - 1);
标记位直接右移s+b位即可得到。
接下来是最为关键的一个函数,即对是否命中进行检查,如果不命中则进行替换。
具体的实现思路位先根据IsHit函数进行判断,如果不命中返回值为-1,此时要调用Replace函数,并对Misses值进行加1操作,如果命中,则要对Hits值进行加1操作。
6.组和各个函数,进行调试
基本的函数已经写完了,还有-v参数和help指令没有解决,接下来先调试一下。
根据将部分信息打印的方法排除了一些基本的错误。最后运行成功。
然而发现得分并不是满分。
只有21分。
./csim -v -s 3 -E 4 -b 33 -t traces/yi.trace
使用这个调试方式进行分析,发现替换过程出了问题。
7.发现错误,进行修改
检查发现LRU算法是没有问题的。
经过调试发现是最关键的函数出了问题,在判断命中之后,也要对LRU值进行更新,而原先没有对LRU值进行更新,导致进行牺牲页调换的时候,LRU值更新失败,页调换异常,Evictions值计算失败。进行修改,只需要在命中判断之后更新一下LRU值即可。
得到满分27分。
但实验内容还没有完全结束。
-v和-h选项还没有实现。
8.实现-v和-h选项
-h实现比较简单,只要把帮助信息打印出来即可。
测试一下,没有问题。
最后是-v选项,不太理解-v选项要做什么,查出来是显示跟踪信息的可选详细标记。就是把从文件中传入的参数打印出来,使用一个verbose值来判断是否判断是否传入了v,如果有,把verbose值设为1,并将传入的参数打印出来。
("%c %lx%c%lu: ",cmd[0],address,Char,number)
打印的内容如上。调试一下。
打印成功。
实验基本完成。
二、
实验总结
因为在上次实验的过程中确立的基本的思路,当然其中也有一些想法参考自其他同学,所以,在本次实验的过程中,具体要做的内容就是要把函数一个一个的实现并组合起来,在最终的组合过程中我花费了很长的时间,因为很多函数我没有找到能够一个一个调试的方法,只能组合到一起进行测试并且根据给出的yitrace文件中的地址进行判断是否正确,因此在最终组合完成之后并没有得到满分,又花了很长的时间去找问题出现在哪。整个过程还是花费了很多的精力,自己应该去学习一下更好更准确的测试方法,以便在今后的开发中能够更快更好地完成任务。