【CSAPP】Cache Lab 实验笔记
cachelab这节先让你实现个高速缓存模拟器,再在此基础上对矩阵转置函数进行优化,降低高速缓存不命中次数。我的感受如上一节,实在是不想研究这些犄角旮旯的优化策略了。
前期准备
我实验的时候用到了valgrind和python,都可以用apt-get大法直接安装
Prat A: 高速缓存模拟器
C语言图书管理系统级别的题目,照着课本硬模拟就行。讲义里说可以用malloc动态分配cache大小,但这东西规模很小,我直接预定义成了个大二维数组。唯一能说的新东西就是getopt了,解答了我一直以来对程序参数处理的标准方案的疑惑。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include "cachelab.h"
#define MAX_CACHE_SET 32
#define MAX_CACHE_LINE 32
#define DEBUG 0
int hit_cnt;
int miss_cnt;
int eviction_cnt;
int cmd_cnt;
int s,E,b;
struct cache_line
{
int valid_bit;
int tag_bit;
int last_time;
}cache[MAX_CACHE_SET][MAX_CACHE_LINE];
void init();
void args_parse(int argc, char *argv[]);
void cmd_parse(char *cmd,long long addr);
void exec_cmd(long long addr);
void addr_parse(long long addr,int *tag_bit,int *set_id);
int main(int argc,char *argv[]);
void init(){
hit_cnt=miss_cnt=eviction_cnt=cmd_cnt=0;
memset(cache,0,sizeof(cache));
return;
}
void args_parse(int argc, char *argv[]){
char ch;
while((ch=getopt(argc, argv,"s:E:b:t:"))!=-1){
switch (ch)
{
case 's':
s=atoi(optarg);
break;
case 'E':
E=atoi(optarg);
break;
case 'b':
b=atoi(optarg);
break;
case 't':
freopen(optarg, "r", stdin);
}
}
return;
}
void cmd_parse(char *cmd,long long addr){
switch (cmd[0])
{
case 'I':
break;
case 'L':
exec_cmd(addr);
break;
case 'S':
exec_cmd(addr);
break;
case 'M':
exec_cmd(addr);
exec_cmd(addr);
break;
}
return;
}
void addr_parse(long long addr,int *tag_bit,int *set_id){
int tmp=0;
for(int i=0;i<s;i++){
tmp=(tmp<<1)+1;
}
*set_id=((int)(addr>>b)&tmp)%(1<<s);
*tag_bit=(int)(addr>>(b+s));
return;
}
void exec_cmd(long long addr){
int tag_bit,set_id;
cmd_cnt++;
addr_parse(addr,&tag_bit,&set_id);
if(DEBUG) printf("%d %d ",set_id,tag_bit);
for(int i=0;i<E;i++){
if((cache[set_id][i].valid_bit)
&&(cache[set_id][i].tag_bit)==tag_bit
){
cache[set_id][i].last_time=cmd_cnt;
hit_cnt++;
if(DEBUG) printf("hit\n");
return;
}
}
miss_cnt++;
for(int i=0;i<E;i++){
if(!cache[set_id][i].valid_bit){
cache[set_id][i].valid_bit=1;
cache[set_id][i].tag_bit=tag_bit;
cache[set_id][i].last_time=cmd_cnt;
if(DEBUG) printf("miss\n");
return;
}
}
eviction_cnt++;
int victim_id=0;
for(int i=0;i<E;i++){
if(cache[set_id][i].last_time<cache[set_id][victim_id].last_time){
victim_id=i;
}
}
cache[set_id][victim_id].tag_bit=tag_bit;
cache[set_id][victim_id].last_time=cmd_cnt;
if(DEBUG) printf("miss eviction\n");
return;
}
int main(int argc,char *argv[])
{
init();
args_parse(argc,argv);
char cmd[10];
long long addr;
int blocksize;
while(~scanf("%s %llx,%d",cmd,&addr,&blocksize)){
cmd_parse(cmd,addr);
}
printSummary(hit_cnt, miss_cnt, eviction_cnt);
return 0;
}
Part B:优化矩阵转置函数
这题用到了一种名为分块(blocking)的技术,指将要处理的大块数据分割为可以放入L1高速缓存的小块,把与这一小块的全部相关操作一次性处理完再切换下一小块,以此来提高L1高速缓存的利用率。块的尺寸可以通过枚举测试或者数学方法分析来决定。
除此之外 ,还可以对高速缓存中的冲突现象进行进一步分析,但如在perflab里所说,我实在懒得研究这种细枝末节的优化,所以只得了个一般般的分数就收手了。
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;
}
最终成绩如下:
Part A: Testing cache simulator
Running ./test-csim
Your simulator Reference simulator
Points (s,E,b) Hits Misses Evicts Hits Misses Evicts
3 (1,1,1) 9 8 6 9 8 6 traces/yi2.trace
3 (4,2,4) 4 5 2 4 5 2 traces/yi.trace
3 (2,1,4) 2 3 1 2 3 1 traces/dave.trace
3 (2,1,3) 167 71 67 167 71 67 traces/trans.trace
3 (2,2,3) 201 37 29 201 37 29 traces/trans.trace
3 (2,4,3) 212 26 10 212 26 10 traces/trans.trace
3 (5,1,5) 231 7 0 231 7 0 traces/trans.trace
6 (5,1,5) 265189 21775 21743 265189 21775 21743 traces/long.trace
27
Part B: Testing transpose function
Running ./test-trans -M 32 -N 32
Running ./test-trans -M 64 -N 64
Running ./test-trans -M 61 -N 67
Cache Lab summary:
Points Max pts Misses
Csim correctness 27.0 27
Trans perf 32x32 6.9 8 343
Trans perf 64x64 1.2 8 1891
Trans perf 61x67 10.0 10 1992
Total points 45.1 53
【CSAPP】Cache Lab 实验笔记的更多相关文章
- 【CSAPP】Shell Lab 实验笔记
shlab这节是要求写个支持任务(job)功能的简易shell,主要考察了linux信号机制的相关内容.难度上如果熟读了<CSAPP>的"异常控制流"一章,应该是可以不 ...
- 【CSAPP】Attack Lab实验笔记
attacklab这节玩的是利用一个字符串进行缓冲区溢出漏洞攻击,就小时候想象中黑客干的事儿. 做题的时候好几次感叹这些人的脑洞,"这都可以攻击?还能这么注入?这还可能借力打力?" ...
- 【CSAPP】Performance Lab 实验笔记
perflab这节的任务是利用书中知识,来对图像处理中的Rotate和Smooth操作函数进行优化.这次没对上电波,觉得学了一堆屠龙之技.于我个人理解,现在计算机配置比以前高多了,连SWAP分区都几近 ...
- 【CSAPP】Architecture Lab 实验笔记
archlab属于第四章的内容.这章讲了处理器体系结构,就CPU是怎样构成的.看到时候跃跃欲试,以为最后实验是真要去造个CPU,配套资料也是一如既往的豪华,合计四十多页的参考手册,一大包的源码和测试程 ...
- 【CSAPP】Bomb Lab实验笔记
bomblab这节搞的是二进制拆弹,可以通俗理解为利用反汇编知识找出程序的六个解锁密码. 早就听闻BOMBLAB的大名,再加上我一直觉得反汇编是个很艰难的工作,开工前我做好了打BOSS心理准备.实际上 ...
- 【CSAPP】Data Lab实验笔记
前天讲到要刚CSAPP,这一刚就是两天半.CSAPP果然够爽,自带完整的说明文档,评判程序,辅助程序.样例直接百万组走起,管饱! datalab讲的是整数和浮点数怎么用二进制表示的,考验的是用基本只用 ...
- ChCore Lab3 用户进程和异常处理 实验笔记
本文为上海交大 ipads 研究所陈海波老师等人所著的<现代操作系统:原理与实现>的课程实验(LAB)的学习笔记的第三篇:用户进程与异常处理.所有章节的笔记可在此处查看:chcore | ...
- CSAPP buffer lab记录——IA32版本
CSAPP buffer lab为深入理解计算机系统(原书第二版)的配套的缓冲区溢出实验,该实验要求利用缓冲区溢出的原理解决5个难度递增的问题,分别为smoke(level 0).fizz(level ...
- CSAPP Bomb Lab记录
记录关于CSAPP 二进制炸弹实验过程 (CSAPP配套教学网站Bomb Lab自学版本,实验地址:http://csapp.cs.cmu.edu/2e/labs.html) (个人体验:对x86汇编 ...
随机推荐
- linux安装maven环境
linux安装maven环境 一. 下载压缩包: 官网地址: http://maven.apache.org/download.cgi 或者百度网盘链接:https://pan.baidu.com/s ...
- React优点?
声明式, 组件化, 一次学习, 随处编写. 灵活, 丰富, 轻巧, 高效
- kafka follower如何与leader同步数据?
Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制.完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率.而异步复制 ...
- @Bean和@Componet区别
无意在两个类上看到了这两个注解,一个使用了@Bean配合@Configuration,一个使用了@Componet.依稀记得这两个注解都是实现以前在xml中<bean xxx/>的功能,但 ...
- 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动 的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联 集合对象时,可以根据对象关系模型直接获取,所以它是全自动的.而 Mybatis 在查询关联对象或关联集 ...
- thrift使用和源码分析
1 前言 thrift的官方文档比较差,很多细节没有介绍清楚,比如require.optional和default字段的区别是什么,为什么字段前面要写序号等,带着这些疑问,我们需要阅读生成的源码来了解 ...
- 经历了源码的痛苦,掌握DRF的核心序列化器
目录 DRF的核心--序列化器 序列化器 什么是序列化和反序列化? 序列化 序列化demo 字段类型 字段参数 序列化自定制返回字段 方法一:在序列化类(serializers.py)中写 方法二:在 ...
- ip地址与子网掩码概述
IP地址: IP地址(Internet Protocol):IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异. IP地址分为五 ...
- #define的3种用法详解
1.#define 的作用 在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为"宏".被定义为"宏"的标识符称为"宏名".在编译 ...
- 11_滞后补偿器_Lag Compensator_Matlab_Simulink
下图中左边没有补偿器的稳态误差,右边是有只猴补偿器的稳态误差,H(s)为滞后补偿器的原因是H(s)bode图的相位图是负的 其中黄线是没有滞后补偿器的,蓝线是滞后补偿器中p = 1 ,q = 9的曲线 ...