这里看不懂的可以先看上一篇
FIFO:
就是先进先出
URL:
哪个块 ,上一次被用到的时间点最早 ,被替换掉
块 , 每一次被用到的时候,都会更新一下时间点
Random:
随机 替换
模拟器正确性的验证:
模拟器实现的正确与否,可以通过读取trace文件,模拟cache运行,再得到输出。比如对于trace5.txt的模拟。
Trace5.txt:
w 10 1对于上述的三个存储访问记录,对于32大小的直接映射缓存而言,上述的三个地址都映射到同一个地址,因此会涉及到2次miss,1次hit。具体的数据如下:
数据取前6位 , 组号 = 数据%8
10H = 00010000 => 数据 : 4 , 组号: 4
30H = 00110000 => 数据 : 12 ,组号 : 4
50H = 01010000 => 数据 : 20 ,组号 : 4
70H = 00110000 => 数据 : 28 ,组号 : 4
90H = 10010000 => 数据 : 36 ,组号 : 4
LRU的话 , 这里刚好比较特殊 , 和FIFO结果刚好一样 ,
但是一旦数据多了 , 就会体会到其中的差别
代码:
Random:
#include
#include
#include
#include
#include
#include
using namespace std;
#define _u32 unsigned int
#define _u8 unsigned int
int main()
{
string buffer;
string str[3];
int count[32][4] = {0}, record[32][4] = {0};//用于记录是否使用过 用1 0 表示
int index1[32] = {0};//记录每个组有多少块已经有数据了
int records;
int temp; //用于random算法中设置随机数
int index=0; //看这个是否是满的
int index2 = 0; //判断组中是否含有该数
ifstream in("trace5.txt");
if (! in.is_open())
{
cout << "Error opening file";
exit (1);
}
_u32 cache_size = 32;
_u32 cache_r_count = 0; /* 读cache次数 */
_u32 cache_w_count = 0; /* 写cache次数 */
_u32 cache_mem_read = 0; /*cache读mem次数;*/
_u32 cache_mem_write = 0; /*cache写mem次数;*/
_u32 cache_hit_count = 0; /*cache命中的次数*/
_u32 cache_miss_count = 0; /*cache缺失的次数*/
_u32 capacity_miss_count = 0; /* 容量缺失 */
_u32 conflict_miss_count = 0; /* 冲突缺失 */
_u32 cache_avaliable;
cache_avaliable = cache_size;//缓存的容量赋值给总的可使用值
int sizecount = 0;
while (!in.eof() )
{
//cout << buffer << endl; getline空格也算一个字符
getline(in, buffer);/*要用#include*/
int s = 0, i;
istringstream stream(buffer);
stream >> str[0] >> str[1] >> str[2]; //一个字符串一个字符串地取出
// 十六进制的字符串转化为十进制的数字
for (i = 0; i<2; i++)
{
if (str[1][i] >= 'a'&& str[1][i] <= 'f')
{
s = s * 16 + str[1][i] - 87;
}
else if (str[1][i] >= '0'&& str[1][i] <= '9')
{
s = s * 16 + str[1][i] - 48;
}
else if (str[1][i] >= 'A' && str[1][i] <= 'F')
{
s = s * 16 + str[1][i] - 55;
}
}
s = s / 4; //除去无用的低两位
//cout << s << " ";//测试输出
//记录初始地址,要和后来的相同的余进行比较原值
records = s;
if(buffer[0] == 'w')
{
cache_w_count++;
//由于是4路组相连 , 所以每个组有四个 , 一共有8个组 , 所以对8求余
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s]; // 记录当前组的被占用块的个数
index2=0;
//判断一下组里有没有和它一样的
//如果有一样的index2 = 1 , 直接hit到了
for(i=0 ; i<4 ; i++){
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2){
cache_hit_count++;
}
//如果组里没有的话
else{
//计数,random
//组里面被占用的块的个数 <4 , 那么接着往里面存
//组内块满之前,不考虑替换策略,按顺序往下排
if (temp < 4){
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
conflict_miss_count++;
//随机找一个0~3之间的数,并将所对应快内的数据替换
temp = rand()%4;
record[s][temp] = records;
cache_mem_write++;
}
}
}
}
//写!!!!
else if(buffer[0] == 'r')
{
cache_r_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2 = 0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2){
cache_hit_count++;
}else{
//计数,random
if (temp<4) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
temp = rand()%4;
record[s][temp] = records;
//cache_mem_write++;
}
}
}
}
}
cout << "cache_r_count =" << cache_r_count << "," << "cache_w_count =" << cache_w_count<< endl;
cout << "cache_mem_read =" << cache_mem_read << "," << "cache_mem_write =" << cache_mem_write << endl;
cout << "cache_hit_count =" << cache_hit_count << "," << "cache_miss_count =" << cache_miss_count << endl;
cout << "capacity_miss_count =" << capacity_miss_count << "," << "conflict_miss_count =" << conflict_miss_count << endl;
cout << "cache_avaliable_size =" << cache_avaliable << endl;
// cout << sizecount;
return 0;
}
FIFO:
#include
#include
#include
#include
#include
#include
using namespace std;
#define _u32 unsigned int
#define _u8 unsigned int
int main()
{
string buffer;
string str[3];
int count[32][4] = {0}, record[32][4] = {0};//用于记录是否使用过 用1 0 表示
int index1[32] = {0};
int records;
int temp; //用于random算法中设置随机数
int index=0; //看这个是否是满的
int index2 = 0; //判断组中是否含有该数
ifstream in("trace6.txt");
if (! in.is_open())
{
cout << "Error opening file";
exit (1);
}
_u32 cache_size = 32;
_u32 cache_r_count = 0; /* 读cache次数 */
_u32 cache_w_count = 0; /* 写cache次数 */
_u32 cache_mem_read = 0; /*cache读mem次数;*/
_u32 cache_mem_write = 0; /*cache写mem次数;*/
_u32 cache_hit_count = 0; /*cache命中的次数*/
_u32 cache_miss_count = 0; /*cache缺失的次数*/
_u32 capacity_miss_count = 0; /* 容量缺失 */
_u32 conflict_miss_count = 0; /* 冲突缺失 */
_u32 cache_avaliable;
cache_avaliable = cache_size;//缓存的容量赋值给总的可使用值
int sizecount = 0;
while (!in.eof() )
{
//cout << buffer << endl; getline空格也算一个字符
getline(in, buffer);/*要用#include*/
int s = 0, i;
istringstream stream(buffer);
stream >> str[0] >> str[1] >> str[2]; //一个字符串一个字符串地取出
// 十六进制的字符串转化为十进制的数字
for (i = 0; i<2; i++)
{
if (str[1][i] >= 'a'&& str[1][i] <= 'f')
{
s = s * 16 + str[1][i] - 87;
}
else if (str[1][i] >= '0'&& str[1][i] <= '9')
{
s = s * 16 + str[1][i] - 48;
}
else if (str[1][i] >= 'A' && str[1][i] <= 'F')
{
s = s * 16 + str[1][i] - 55;
}
}
s = s / 4; //除去无用的低两位
//记录初始地址,要和后来的相同的余进行比较原值
records = s;
//读!!!!!
if(buffer[0] == 'w')
{
cache_w_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2=0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2){
cache_hit_count++;
}else{
//计数,random
if (count[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
cache_mem_write++;
index1[s]++;
index1[s] = index1[s]%4;
}
}
}
}
//写!!!!
else if(buffer[0] == 'r')
{
cache_r_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2 = 0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2){
cache_hit_count++;
}else{
//计数,random
if (count[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
//cache_mem_write++;
index1[s]++;
index1[s] = index1[s]%4;
}
}
}
}
}
cout << "cache_r_count =" << cache_r_count << "," << "cache_w_count =" << cache_w_count<< endl;
cout << "cache_mem_read =" << cache_mem_read << "," << "cache_mem_write =" << cache_mem_write << endl;
cout << "cache_hit_count =" << cache_hit_count << "," << "cache_miss_count =" << cache_miss_count << endl;
cout << "capacity_miss_count =" << capacity_miss_count << "," << "conflict_miss_count =" << conflict_miss_count << endl;
cout << "cache_avaliable_size =" << cache_avaliable << endl;
// cout << sizecount;
return 0;
}
LRU:
#include
#include
#include
#include
#include
#include
using namespace std;
#define _u32 unsigned int
#define _u8 unsigned int
int main()
{
string buffer;
string str[3];
int count[32][4] = {0}, record[32][4] = {0};//用于记录是否使用过 用1 0 表示
int time[32][4] = {0};
int index1[32] = {0};
int records;
int temp; //用于random算法中设置随机数
int index=0; //看这个是否是满的
int index2 = 0; //判断组中是否含有该数
int TimeSum = 0;
int ways = 0;
cout << "请问你要用哪种方式:1.FIFO替换策略 2.LRU替换策略" <> ways;
ifstream in("trace1.txt");
if (! in.is_open())
{
cout << "Error opening file";
exit (1);
}
_u32 cache_size = 32;
_u32 cache_r_count = 0; /* 读cache次数 */
_u32 cache_w_count = 0; /* 写cache次数 */
_u32 cache_mem_read = 0; /*cache读mem次数;*/
_u32 cache_mem_write = 0; /*cache写mem次数;*/
_u32 cache_hit_count = 0; /*cache命中的次数*/
_u32 cache_miss_count = 0; /*cache缺失的次数*/
_u32 capacity_miss_count = 0; /* 容量缺失 */
_u32 conflict_miss_count = 0; /* 冲突缺失 */
_u32 cache_avaliable;
cache_avaliable = cache_size;//缓存的容量赋值给总的可使用值
int sizecount = 0;
while (!in.eof() )
{
//cout << buffer << endl; getline空格也算一个字符
getline(in, buffer);/*要用#include*/
int s = 0, i;
istringstream stream(buffer);
stream >> str[0] >> str[1] >> str[2]; //一个字符串一个字符串地取出
// 十六进制的字符串转化为十进制的数字
for (i = 0; i<2; i++)
{
if (str[1][i] >= 'a'&& str[1][i] <= 'f')
{
s = s * 16 + str[1][i] - 87;
}
else if (str[1][i] >= '0'&& str[1][i] <= '9')
{
s = s * 16 + str[1][i] - 48;
}
else if (str[1][i] >= 'A' && str[1][i] <= 'F')
{
s = s * 16 + str[1][i] - 55;
}
}
s = s / 4; //除去无用的低两位
//记录初始地址,要和后来的相同的余进行比较原值
records = s;
if(ways == 2){
//读!!!!!
if(buffer[0] == 'w')
{
cache_w_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2=0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2)
{
cache_hit_count++;
time[s][i] = TimeSum;
TimeSum++;
//cout << '2' << time[s][i] << record[s][i]<< endl;
}
else
{
if (record[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
time[s][temp] = TimeSum;
TimeSum++;
}
else //若有记录
{
//找到用的次数最少的那个数据
temp = 0;
for(i=0 ; i<4 ; i++)
{
if(time[s][temp]>time[s][i]){
temp = i;
}
}
//cout << temp << endl;
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
cache_mem_write++;
time[s][temp] = TimeSum;
TimeSum++;
}
}
}
}
//写!!!!
else if(buffer[0] == 'r')
{
cache_r_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
index2 = 0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
time[s][i] = TimeSum;
TimeSum++;
break;
}
}
if(index2)
{
cache_hit_count++;
}
else
{
//计数,random
if (count[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
}
else //若有记录
{
//找到用的次数最少的那个数据
temp = 0;
for(i=0 ; i<4 ; i++)
{
if(time[s][temp]>time[s][i]){
temp = i;
}
}
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
}
}
index1[s]++;
index1[s] = index1[s]%4;
time[s][i] = TimeSum;
TimeSum++;
}
}
}
else if(ways == 1)
{
//读!!!!!
if(buffer[0] == 'w')
{
cache_w_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2=0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2)
{
cache_hit_count++;
}
else
{
//计数,random
if (count[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
cache_mem_write++;
index1[s]++;
index1[s] = index1[s]%4;
}
}
}
}
//写!!!!
else if(buffer[0] == 'r')
{
cache_r_count++;
if (s >= 8) //大于8时进行求余
{
s = s % 8;
}
index = 0;
temp = index1[s];
index2 = 0;
for(i=0 ; i<4 ; i++)
{
if(record[s][i] == records)
{
index2 = 1;
break;
}
}
if(index2)
{
cache_hit_count++;
}
else
{
//计数,random
if (count[s][temp] == 0) //若没有记录
{
count[s][temp] = 1;
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
conflict_miss_count++; //冲突记录
record[s][temp] = records; //将之前的s记录并用于之后的比较
if(cache_avaliable > 0) //如果缓存还有的话
{
cache_avaliable--;
}
index1[s]++;
index1[s] = index1[s]%4;
}
else //若有记录
{
if (sizecount >= cache_size) //记录拿了多少内存 若超出即是内存冲突
{
capacity_miss_count++;
conflict_miss_count--; //要减去之前都加一的缺失冲突
} //超出缓存范围
else//如果没记录就说明是另外的地址 虽然重复但还是缺失
{
cache_miss_count++;
cache_mem_read++;//不管是读还是写,没有都要去读取的
sizecount++; //记录容量的分配和使用
//如果该组中满了,其他组还可以用,那么久发生conflict_miss_count冲突
for(i=0 ; i<4 ; i++)
{
if(count[s][i] == 0)
{
index = 1;
break;
}
}
if(!index)
conflict_miss_count++;
record[s][temp] = records;
//cache_mem_write++;
index1[s]++;
index1[s] = index1[s]%4;
}
}
}
}
}
}
cout << "cache_r_count =" << cache_r_count << "," << "cache_w_count =" << cache_w_count<< endl;
cout << "cache_mem_read =" << cache_mem_read << "," << "cache_mem_write =" << cache_mem_write << endl;
cout << "cache_hit_count =" << cache_hit_count << "," << "cache_miss_count =" << cache_miss_count << endl;
cout << "capacity_miss_count =" << capacity_miss_count << "," << "conflict_miss_count =" << conflict_miss_count << endl;
cout << "cache_avaliable_size =" << cache_avaliable << endl;
// cout << sizecount;
return 0;
}