【深入理解计算机系统csapp】 cache lab 实验五

实验准备知识

csapp2015年学习讲义ppt

1.寄存器等级介绍

在这里插入图片描述
在这里插入图片描述

2. 主存地址

在这里插入图片描述

  • 按字节编址,块内地址block offset有b位,cache组号set index有s位,标记tag位有address size-b-s位。

3. 缓存Cache

在这里插入图片描述

  • cache有 2 s 2^s 2s行,一行有E组(当E等于1时为全相联映射)
  • 每个cache块中有 2 b 2^b 2b字节个数据
  • 总容量有 s ∗ b ∗ e s*b*e sbe

4. 图示

在这里插入图片描述

5. Cache中的命中率和缺失率

Hit:要访问的信息在cache中

  • Hit Rate:在cache中的概率
  • Hit Time:在cache中访问的时间:判断时间+cache访问
    Miss:要找的信息不在cache中
  • Miss Rate:1-Hit Rate
  • Miss Penalty(缺失损失):访问一个主存块所花的时间

6. LRU算法

总是把最先进入的那一块淘汰掉。

  • LRU是栈算法,命中率随组的增大而提高。
  • 当分块局部化范围(即某段时间集中访问的存储区)超过了cache存储容量时,命中率变得很低。极端情况下,假设地址流是1,2,3,4,1,2,3,4,1……,而cache每组只有3行,那么不管是FIFO算法还是LRU算法,其命中率都是0。这种现象为颠簸现象。
  • LRU具体实现是,并不是通过移动块来实现的,而是通过给每个cache行设定一个计数器,根据计数器的值来记录这些主存块的使用情况。这个计数位成为LRU位。
  • 计数器变化规则如下图。
    在这里插入图片描述

part A

实验A要求模拟一个cache存储器。需要识别不同的s,b,E即不同的set index,block offset,lines来完成数据的存储和释放,如果当cache满了的时候需要使用LRU(最近最少用算法)对数据进行丢弃和存储。

  1. 定义结构体在这里插入图片描述
typedef struct{
	int valid_bits;		//有效位
	unsigned  tag;		//标记位
	int stamp;			//时间戳
}cache_line;

  1. 定义cache[S][E] 大小的二维数组
  2. cache运行的模拟
    读入要访问的地址,查找是否在cache中,若在读内容,若不在在主存中找到后写入cache
operatorwhatdo what
Iinstruction
Ldata load读access cache
Sdata store写access cache
Mdata modify又读又写access cache两次
while((opt = getopt(argc,argv,"s:E:b:t:")) !=-1){           //parse command line arguments
		switch(opt){
		case 's':
			s=atoi(optarg);
			break;
		case 'E':
			E=atoi(optarg);
			break;
		case 'b':
			b=atoi(optarg);
			break;
		case 't':
			filepath = optarg;
			break;
		}
	}
  1. 更新cache
    若命中hit++
    若没有命中miss
void update(unsigned address){
	unsigned s_address =(address>>b) & ((0xffffffff)>>(32-s));                //set`s index
	unsigned t_address = address>>(s+b);                                 //tag`s index
	//判断tag为是否相等,是否命中
    for(int i=0;i<E;i++){
		if((*(cache+s_address)+i)->tag ==t_address){
			cache[s_address][i].stamp = 0;       //now ,this is used
			hit++;
			return;
		}
	}
    //更新高速缓存cache
	for(int i=0;i<E;i++){
		if(cache[s_address][i].valid_bits == 0){
			cache[s_address][i].tag = t_address;
			cache[s_address][i].valid_bits = 1;
			cache[s_address][i].stamp = 0;       //now ,this is load
			miss++;
			return;
		}
	}
    //暴力实现LRU策略
	int max_stamp=0;
	int max_i;
	for(int i=0;i<E;i++){
		if(cache[s_address][i].stamp > max_stamp){
			max_stamp = cache[s_address][i].stamp;
			max_i = i;
		}
	}
	eviction++;
	miss++;
	cache[s_address][max_i].tag = t_address;
	cache[s_address][max_i].stamp = 0;	
}
  1. 时间戳
    若使用cache,stamp为0
void time(){
	for(int i=0;i<S;i++){
		for(int j=0;j<E;j++){
			if(cache[i][j].valid_bits == 1)
				cache[i][j].stamp++;		
		}	
	}
}

完整代码实现

#include "cachelab.h"
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stddef.h>
typedef struct{
	int valid_bits;
	unsigned  tag;
	int stamp;
}cache_line;
char* filepath = NULL;
int s,E,b,S;           // s is set ,E  is line,each line have 2^b bits ,S is 2^s set
int hit=0,miss=0,eviction=0;
cache_line** cache = NULL;

void init(){
	cache = (cache_line**)malloc(sizeof(cache_line*)*S);             //malloc cache[S][E]
	for(int i=0;i<S;i++)
		*(cache+i) = (cache_line*)malloc(sizeof(cache_line)*E);
	for(int i=0;i<S;i++){
		for(int j=0;j<E;j++){
			cache[i][j].valid_bits = 0;      // set all valid_bits is zero
			cache[i][j].tag = 0xffffffff;           //no address
			cache[i][j].stamp = 0;            //time is 0;		
		}	
	}
}

void update(unsigned address){
	unsigned s_address =(address>>b) & ((0xffffffff)>>(32-s));                //set`s index
	unsigned t_address = address>>(s+b);                                 //tag`s index
	//判断tag为是否相等,是否命中
    for(int i=0;i<E;i++){
		if((*(cache+s_address)+i)->tag ==t_address){
			cache[s_address][i].stamp = 0;       //now ,this is used
			hit++;
			return;
		}
	}
    //更新高速缓存cache
	for(int i=0;i<E;i++){
		if(cache[s_address][i].valid_bits == 0){
			cache[s_address][i].tag = t_address;
			cache[s_address][i].valid_bits = 1;
			cache[s_address][i].stamp = 0;       //now ,this is load
			miss++;
			return;
		}
	}
    //暴力实现LRU策略
	int max_stamp=0;
	int max_i;
	for(int i=0;i<E;i++){
		if(cache[s_address][i].stamp > max_stamp){
			max_stamp = cache[s_address][i].stamp;
			max_i = i;
		}
	}
	eviction++;
	miss++;
	cache[s_address][max_i].tag = t_address;
	cache[s_address][max_i].stamp = 0;	
}
void time(){
	for(int i=0;i<S;i++){
		for(int j=0;j<E;j++){
			if(cache[i][j].valid_bits == 1)
				cache[i][j].stamp++;		
		}	
	}
}
int main(int argc,char *argv[])
{
	int opt;         
	while((opt = getopt(argc,argv,"s:E:b:t:")) !=-1){           //parse command line arguments
		switch(opt){
		case 's':
			s=atoi(optarg);
			break;
		case 'E':
			E=atoi(optarg);
			break;
		case 'b':
			b=atoi(optarg);
			break;
		case 't':
			filepath = optarg;
			break;
		}
	}
	S = 1<<s;
	init();
	FILE* file=fopen(filepath,"r");
	if(file == NULL){     // read trace file
		printf("Open file wrong");		
		exit(-1);
	}
	char operation;
	unsigned address;
	int size;	
	while(fscanf(file," %c %x,%d",&operation,&address,&size)>0){
		switch(operation){
			case 'L':
				update(address);
				break;
			case 'M':
				update(address);
			case 'S':
				update(address);
				break;
		}
		time();
	}
	for(int i=0;i<S;i++)                  //free cache[S][E]
		free(*(cache+i));
	free(cache);
	fclose(file);	                //close file	
    printSummary(hit,miss,eviction);
    return 0;
}

在这里插入图片描述

part B

实现矩阵的转置,采用分治(分块)的思想:一块一块搬乘转置。

void transpose_submit(int M, int N, int A[N][M], int B[M][N])
{
    int rr,cc,r,c;
    int bsize;
    if(M==32) bsize=8;
    else if(M==64) bsize=4;
    else if(M==61) bsize=16;
    for(rr=0;rr<N;rr+=bsize){
        for(cc=0;cc<M;cc+=bsize){
            for(r=rr;r<N&&r<rr+bsize;r++){
                for(c=cc;c<M&&c<cc+bsize;c++){
                    B[c][r]=A[r][c];
                }
            }
        }
    }
    return;
}

在这里插入图片描述

参考文章

https://www.cnblogs.com/kangyupl/p/13263687.html
https://cloud.tencent.com/developer/article/1826689
https://blog.csdn.net/weixin_41256413/article/details/81388351
https://zhuanlan.zhihu.com/p/33846811
https://zhuanlan.zhihu.com/p/42754565

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lydia.na

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值