csapp实验记录 - Cachelab partA
Cachelab partA
这是该实验的 partA 部分,主要是用 c 语言模拟 cpu 对cache的存取过程,以及其缓存命中,不命中和不命中时的替换的情况
实验准备
实验的环境在 Linux
具体的实验包可以去 CMU 的csapp实验官网下载
实验
同时该实验 CMU 有相应的辅助材料可以利用
实验指导PPT
解答
本实验就是简单模拟缓存的行为
注意
- 本实验需要根据传入的不同的 s,E,bs, E, bs,E,b 值进行模拟
- 替换策略使用LRU(最近最少使用)策略
数据结构
所以根据此可以创建一个存储缓存行的结构体
typedef struct CACHE_LINE {short valid; // 有效位unsigned tag; // 标记int stamp; // 模拟时间戳,用于lru
}cache_line, *cache_asso, **cache;
同时定义该结构体的指针和指针的指针,便于后续 malloc 二维数组来模拟 cache
具体思路
那么结构体有了,我们需要做的就是根据给出的 s,E,bs, E, bs,E,b 的值 malloc 出二维数组
有了二维数组,我们就可以读取每一条指令,将指令的地址字段解析出 标记 和 组索引
根据组索引和标记模拟命中情况,记录命中和不命中,替换的次数
替换策略采用简单版的LRU,具体算法如下:
- 对于每一次缓存动作,将定位的块中所有的缓存行的 stamp + 1,模拟时间推移
- 对命中的缓存行,stamp = 0
- 替换掉 stamp 值最大的缓存行
代码
#include "cachelab.h"
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>typedef struct CACHE_LINE {short valid;unsigned tag;int stamp;
}cache_line, *cache_asso, **cache;cache _cache_ = NULL;int s, S, E, b, v;
char t[1024];
int hits, misses, evictions;int init_cache();void free_cache();unsigned get_block_index(unsigned address);unsigned get_tag(unsigned address);void visit_cache();int hit_cache(unsigned index, unsigned tag);int main(int argc, char **argv)
{int opt;while((opt = getopt(argc, argv, "vs:E:b:t:")) != -1) {switch(opt) {case 'v':v = 1;break;case 's':s = atoi(optarg);break;case 'E':E = atoi(optarg);break;case 'b':b = atoi(optarg);break;case 't':strcpy(t,optarg);break;default:printf("wrong arg!");break;}}if(s <= 0 || E <= 0 || b <= 0 || t == NULL) return -1;S = 1 << s;init_cache();visit_cache();free_cache();printf("hits:%d misses:%d evictions:%d\n",hits,misses,evictions);printSummary(hits,misses,evictions);return 0;
}int init_cache() {_cache_ = (cache)malloc(sizeof(cache_asso) * S);if(_cache_ == NULL) return -1;for(int i = 0;i < S;i ++) {_cache_[i] = (cache_asso)malloc(sizeof(cache_line) * E);if(_cache_[i] == NULL) return -1;for(int j = 0;j < E;j ++) {_cache_[i][j].valid = 0;_cache_[i][j].tag = -1;_cache_[i][j].stamp = 0;}}return 1;
}void free_cache() {if(_cache_ != NULL) {for(int i = 0;i < S;i ++) {if(_cache_[i] != NULL) free(_cache_[i]);}free(_cache_);}}// 解析缓存块
unsigned get_block_index(unsigned address) {return address >> b & ((1 << s) - 1);
}// 解析缓存行
unsigned get_tag(unsigned address) {return address >>= (b + s);
}// 模拟缓存动作
void visit_cache() {FILE *f;f = fopen(t, "r");char ident;unsigned address;int size;int status; while(fscanf(f," %c %x,%d",&ident, &address, &size) > 0) {unsigned index = get_block_index(address);unsigned tag = get_tag(address);switch(ident) {case 'I':continue;case 'S':case 'L':status = hit_cache(index,tag);if(status == 0) printf("%c %x,%d hit",ident,address,size);else if(status == 1) printf("%c %x,%d miss",ident,address,size);else printf("%c %x,%d miss eviction",ident,address,size);puts("");break;case 'M':status = hit_cache(index,tag);hits ++;if(status == 0) printf("%c %x,%d hit hit",ident,address,size);else if(status == 1) printf("%c %x,%d miss hit",ident,address,size);else printf("%c %x,%d miss eviction hit",ident,address,size);puts("");break;}}fclose(f);
}/*模拟命中情况0 hit1 miss2 miss eviction*/
int hit_cache(unsigned index, unsigned tag) {cache_asso cache_block = _cache_[index];// update lrufor(int i = 0;i < E;i ++) cache_block[i].stamp ++;// hitfor(int i = 0;i < E;i ++) {if(cache_block[i].valid && cache_block[i].tag == tag) {cache_block[i].stamp = 0;hits ++;return 0;}}// missfor(int i = 0;i < E;i ++) {if(!cache_block[i].valid) {cache_block[i].valid = 1;cache_block[i].tag = tag;cache_block[i].stamp = 0;misses ++;return 1;}}int idx = 0;int maxv = 0;for(int i = 0;i < E;i ++) {if(cache_block[i].stamp > maxv) {maxv = cache_block[i].stamp;idx = i;}}cache_block[idx].tag = tag;cache_block[idx].valid = 1;cache_block[idx].stamp = 0;misses ++;evictions ++;return 2;
}
结果
满分27分
总结
partA 部分断断续续花了挺长时间才做完,在学校学 csapp 时间实在是太零碎了,但是一开始很迷茫,看了一下实验指导PPT以及一些细小的地方参考了其它博客,就逐渐清晰了,写代码就很快了。
写完之后测过几个 trace 就去测试了,一遍过了,还是挺有成就感的
csapp实验记录 - Cachelab partA相关推荐
- CSAPP实验记录(二)Bomb Lab
CSAPP实验记录(二)Bomb Lab 二进制炸弹是由一系列阶段组成的程序.每个阶段都要求你在 stdin 上键入一个特定的字符串.如果你输入了正确的字符串,那么这个阶段就被拆除,炸弹进入下一个阶段 ...
- CSAPP实验记录(一):环境配置datalab
CSAPP实验记录(一):环境配置&datalab 1.环境配置 下载Ubuntu虚拟机.我之前用的是Ubuntu18.04,非常坑,强烈建议换成Ubuntu20.04 windows和Ubu ...
- CSAPP实验记录(1)--------- DataLab
Datalab Datalab实验是关于数据的机器级表示,实验要求实现给定的位级运算符,同时要满足一些要求,如只能使用某些限定的运算符,运算符总数不超过某数字等.第一次刷感觉难度还是很大的. 题目一: ...
- CSAPP实验记录(2)--------- Bomb
实验简介 本实验需要拆除一个"二进制炸弹","二进制炸弹"是一个可执行目标程序.运行时,它会提示用户键入6个不同的字符串.如果其中任何一个错误,炸弹就会&quo ...
- 实验记录配置华为NAT Server
1)将内部地址10.1.1.11/24的80端口静态转换为公网地址200.1.1.11/28的80端口,以便被外网(Client2)访问:同时Server1和Client2可以互相ping通. 2)将 ...
- eNSP动态NAT实验记录
将内部网络10.1.1.0/24转换为公网地址200.1.1.1-200.1.1.10/28上网(访问Server3),并抓包分析 验证动态NAT是单向转换 搭建实验环境 实现此案例需要按照如下步骤进 ...
- CSAPP实验——DataLab
CSAPP - DataLab CSAPP实验记录 Data Lab 实验的内容是关于计算机信息的表示,主要包括位操作.整型及浮点型相关知识. 题目列表 名称 任务 难度 bitXor(x, y) ...
- CSAPP Lab2 实验记录 ---- Bomb Lab(Phase 1 - Phase 6详细解答 + Secret Phase彩蛋解析)
文章目录 Lab 总结博客链接 实验前提引子 实验需要指令及准备 Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 Phase 6 Phase Secret(彩蛋Phas ...
- CSAPP Lab5实验记录 ---- Shell Lab(实验分析 + 完整代码)
文章目录 Lab 总结博客链接 前引 Lab5 Shell Lab 1.获取相关Lab材料 2.Overview(总览) 3.Explore(实现前的摸索) 4.函数实现 + 实现代码分析 1.eva ...
最新文章
- python requests max retries_我可以为request.request设置max_retries吗?
- 一、mysql分表简单介绍
- 区块链与边缘计算(2)功能介绍
- mllib逻辑回归 spark_《Spark大数据分析实战》笔记
- 引入SpringBoot Jpa依赖后,项目出现警告
- Orchard核心机制
- unix解释器文件详解
- 小米浏览器html文件怎么打开方式,怎么设置浏览器-开启小米浏览器这三个功能,切换、搜索、编辑都让你事半功倍...
- 苹果推送证书不受信任解决办法2022年
- Auto CAD线性不显示的解决办法
- GNSS说第(四)讲---最新最全的IGS分析中心详情
- 现场总线---can总线
- FL Studio20.9DAW宿主电子音乐制作软件
- file_get_contents获取参数并用file_put_contents保存图片
- peek java linkedlist_Java LinkedList peek()方法
- platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架
- linux 实时性 100ms,实时录播延迟长达100ms
- iview中Table的render用法大全
- PHP 7.2 中废弃的方法
- 谷歌浏览器(Google Chrome) v83.0.4103.97 正式版介绍及下载