CSAPP fall2015 深入理解计算机系统 Cache lab详解

Cache Lab

cache lab 缓存实验

代码下载

从CSAPP上面下载对应的lab代码

http://csapp.cs.cmu.edu/3e/labs.html

环境准备

需要安装 valgrind。可以参考文章Valgrind centos。

安装好以后执行valgrind --version可以看到版本号。

Cache simulator

  • cache simulator not a cache。我们不是实现一个真正的缓存,只是实现一个模拟器。
  • 不存储内容
  • 不使用block offset
  • 只计算命中数,不命中数和驱逐数(hit count, miss count,eviction count)
  • 缓存模拟器需要在不同的s,b,E下运行。
  • 使用LRU替换策略

Hints

  • 使用二维数组 struct cache_line cache[S][E];
  • S = 2^s
  • cache_line //上面说了不需要block offset,所以可以忽略block的内容
    • Valid bit
    • Tag
    • LRU counter
  • 通过getopt获取命令行输入
    • 返回-1表示没有输入了
    • 通常在循环里面接收参数
    • 需要包含#include <unistd.h>,#include <getopt.h>
    • 通常使用switch来处理不同的输入
    • 考虑如何处理无效输入
    • 更多信息 man 3 getopt
  • fscanf可以指定要读的流(scanf只能读标准输入流),用来读取trace file
    • 参数
      • 一个流的指针
      • 如何解析文件的信息的格式化字符串
      • 其余部分是指向存储解析数据的变量的指针
    • 通常在循环里使用
    • 当命中EOF或者没有匹配到格式化字符串的时候返回-1
    • 更多信息 man fscanf
  • Malloc/free
    • malloc分配数据到heap
    • 记得 free 掉malloc的数据
    • 不要 free 你没有分配的内存

在这里插入图片描述

在这里插入图片描述

要求我们实现csim.c文件,给了一个示例csim-ref文件。

输入./csim-ref -h可以看到我们要实现的东西。

在这里插入图片描述

首先需要接受参数,参数有

  • -h 输出帮助信息
  • -v 可选详细标志,根据示例程序来,就是输出 L 10,1 miss这些信息
  • -s [num] set index bit 数
  • -E [num] 每个set的行数
  • -b [num] block offset bit数
  • -t [file] Trace file文件路径

根据上面的提示可以知道,通过getopt函数来接收参数,并通过switch来处理。读取文件则通过fscanf函数,来读取-t传的文件。

下面是./traces/yi.trace文件的内容

 L 10,1M 20,1L 22,1S 18,1L 110,1L 210,1M 12,1
  • L 代表数据载入
  • S 代表数据存储
  • M 代表数据修改,需要一次载入 + 一次存储
  • 后面的10,20,22这些代表地址
  • 最后的1代表操作内存访问的字节数

完整代码

#include "cachelab.h"
#include <unistd.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>typedef struct{int valid;int tag;int time_stamp;
} cache_line;int timestamp = 0;// 开始匹配到合适的set 找到命中的cache,如果命中返回1,如果没有命中返回0
int find_hit_cache(cache_line *cache_line,int E,int tag, int*hits) {int isHit = 0;// 循环set中的cache_line 找到是否有匹配tag && validfor(int i = 0; i < E; i++) {if (cache_line[i].valid == 1 && cache_line[i].tag == tag ) {//hitprintf("hit \n");*hits = *hits + 1;isHit = 1;//刷新时间cache_line[i].time_stamp = timestamp;return isHit;}}return isHit;
}// 找到一个空的cache line放进去,找到了就返回1,没有找到就返回0
int find_empty_cache(cache_line *cache_line,int E,int tag) {int have_empty_cache = 0;for (int i = 0; i< E; i++) {if (cache_line[i].valid == 0) {// 空的// 把当前内存放入cachecache_line[i].valid = 1;cache_line[i].tag = tag;cache_line[i].time_stamp = timestamp;// 找到了就不需要替换了have_empty_cache = 1;return have_empty_cache;}}return have_empty_cache;
}// 获取要替换的索引
int get_eviction_index(cache_line *cache_line, int E) {int max_time_stamp = timestamp;int eviction_index = -1;for (int i = 0; i< E; i++) {if (cache_line[i].time_stamp < max_time_stamp) {//找到time_stamp最小的那个max_time_stamp = cache_line[i].time_stamp;eviction_index = i;}}return eviction_index;
}// LRU替换
void LRU(cache_line *cache_line, int E,int tag) {// 获取要替换的索引int eviction_index = get_eviction_index(cache_line, E);// 替换cache_line[eviction_index].valid = 1;cache_line[eviction_index].tag = tag;cache_line[eviction_index].time_stamp = timestamp; 
}// L和S操作,M就调用两次这个
int load_and_store(unsigned address,int b,int s,int u_max,int E,cache_line **cache, int *hits,int *misses,int *evications) {// 获取set index block offset tagint set_index,tag;set_index = (address >> b) & u_max;tag = (address >> b) >> s;// 开始匹配到合适的set 找到命中的cache,如果命中返回1,如果没有命中返回0int isHit = find_hit_cache(cache[set_index], E, tag, hits);if (isHit == 0) {// missprintf("miss \n");*misses = *misses + 1;// 找到一个空的cache line放进去,找到了就返回1,没有找到就返回0int have_empty_cache = find_empty_cache(cache[set_index], E, tag);// 如果没有找到空的cache,就需要LRU替换if (have_empty_cache == 0) {printf("evictions \n");*evications = *evications + 1;//LRU替换LRU(cache[set_index], E, tag);}}// 更新全局时间戳timestamp++;return 0;
}int main(int argc, char** argv)
{// 接受参数 getoptint opt,v,s,E,b,S,B;// 文件FILE        *       pFile;while(-1 != (opt = getopt(argc, argv, "h?v?s:E:b:t:"))){// opt is h,v,s,E,b,t的ASCII码值// 通过switch对不同的参数进行不同的处理switch(opt) {case 'h':printf("./csim: Missing required command line argument \n Usage: ./csim-ref [-hv] -s <num> -E <num> -b <num> -t <file> \n Options: \n -h         Print this help message. \n -v         Optional verbose flag. \n -s <num>   Number of set index bits. \n -E <num>   Number of lines per set. \n -b <num>   Number of block offset bits. \n -t <file>  Trace file. \n\n Examples: \n ./csim -s 4 -E 1 -b 4 -t traces/yi.trace \n ./csim -v -s 8 -E 2 -b 4 -t traces/yi.trace \n");// h参数输出帮助内容break;case 'v':// v参数输出详细信息v = 1;printf("v:%d \n",v);break;case 's':// S is set 2^s 的数量// s is Number of set index bitss = atoi(optarg);S = 1 << s;printf("s:%d, S:%d \n",s,S);break;case 'E':// E is cache line 的数量// Number of lines per setE = atoi(optarg);printf("E:%d \n",E);break;case 'b':// B is block data 的字节// b is Number of block offset bitsb = atoi(optarg);B = 1 << b;printf("b:%d, B:%d \n",b,B);break;case 't':// t is Trace file// 读取文件//t = atoi(optarg);pFile   =       fopen(optarg,"r");printf("t:%s, file:%p \n",optarg,pFile);break;default:printf("非法参数 \n");break;}}if(s == 0 || E == 0 || b == 0) {return 0;}// cache存储cache_line **cache = (cache_line **)malloc(S * sizeof(cache_line *));if (cache == NULL) {printf("内存分配失败 \n");}for(int i = 0; i < S; i++) {cache[i] = (cache_line *)malloc(E * sizeof(cache_line));if(cache[i] == NULL) {printf("内存分配失败,开始回滚 \n");// 在这里需要释放已分配的内存,然后退出for (int j = 0; j < i; ++j) {free(cache[j]);}free(cache);}}int u_max = 1; for(int i = 0; i < s - 1; i++) {u_max = (u_max << 1) | 1;}// 读取文件char        identifier;unsigned    address;int         size;int hits,misses,evictions;
//      Reading lines   like    "       M       20,1"   or      "L      19,3"while(fscanf(pFile," %c %x,%d",&identifier,&address,&size)>0){//      Do      stuff// 开始计算 hits,misses,evictions, hits:0 misses:0 evictions:0//printf("identifier %c, addr:%x, size:%d \n",identifier,address,size);//根据identifier来判断动作L load S store M = 一次L 一次Sif (identifier == 'L' || identifier == 'S'){printf("identifier %c, addr:%x, size:%d \n",identifier,address,size);load_and_store(address,b,s,u_max,E,cache,&hits,&misses,&evictions);} else if (identifier == 'M') {// 一次L 一次Sprintf("identifier %c, addr:%x, size:%d \n",identifier,address,size);load_and_store(address,b,s,u_max,E,cache,&hits,&misses,&evictions);load_and_store(address,b,s,u_max,E,cache,&hits,&misses,&evictions);}}fclose(pFile);  //remember      to      close   file    when    doneprintSummary(hits, misses, evictions);// 释放数组内存for(int i = 0; i< S; i++) {free(cache[i]);}free(cache);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/650876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ART: Automatic multi-step reasoning and tool-use for large language models 导读

ART: Automatic multi-step reasoning and tool-use for large language models 本文介绍了一种名为“自动推理和工具使用&#xff08;ART&#xff09;”的新框架&#xff0c;用于解决大型语言模型&#xff08;LLM&#xff09;在处理复杂任务时需要手动编写程序的问题。该框架可…

【音视频原理】音频编解码原理 ③ ( 音频 比特率 / 码率 | 音频 帧 / 帧长 | 音频 帧 采样排列方式 - 交错模式 和 非交错模式 )

文章目录 一、音频 比特率 / 码率1、音频 比特率2、音频 比特率 案例3、音频 码率4、音频 码率相关因素5、常见的 音频 码率6、视频码率 - 仅做参考 二、音频 帧 / 帧长1、音频帧2、音频 帧长度 三、音频 帧 采样排列方式 - 交错模式 和 非交错模式1、交错模式2、非交错模式 一…

排序问题上机考试刷题

排序与查找可以说是计算机领域最经典的问题&#xff0c;排序和查找问题在考研机试真题中经常出现。排序考点在历年机试考点中分布广泛。排序既是考生必须掌握的基本算法&#xff0c;又是考生 学习其他大部分算法的前提和基础。首先学习对基本类型的排序。对基本类型排序&#x…

【C++中的STL】函数对象

函数对象 函数对象概念谓词概念 内建函数对象算术仿函数关系仿函数逻辑仿函数&#xff08;基本用不到&#xff09; 函数对象概念 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff0c;函数对象使用重载的()时。行为类似函数调用&#xff0c;也叫仿函数。 函数…

分析crash日志

每一天都要快乐的进步~~ 文章目录 在分析 crash 日志时&#xff0c;通常需要关注以下信息&#xff1a; 1️⃣ 错误信息&#xff1a;了解 crash 的具体错误信息&#xff0c;这有助于定位问题的根源所在。 2️⃣ 堆栈跟踪&#xff1a;查看堆栈跟踪&#xff0c;确定 crash 发生的…

4.F1 评分机器学习模型性能的常用的评估指标

F1评分作为机器学习领域中的一个综合性评价指标&#xff0c;旨在在准确率和召回率之间寻求平衡&#xff0c;进而提供对模型性能全面评估的手段。本文将深入探讨F1评分的定义、计算方法、应用领域、案例研究以及未来发展方向&#xff0c;力求为读者提供详实而全面的了解。 一.F…

C#学习笔记_StringBuilder+程序效率测试

String问题&#xff1a;当程序中进行过多字符串处理操作时&#xff0c;会在内存中产生过多垃圾信息&#xff0c;影响程序效率。 StringBuilder简介 StringBuilder为一个类&#xff0c;属于引用类型。StringBuilder与string的区别在于&#xff0c;StringBuilder对于字符串的操…

osgEarth真HelloWorld

osgEarth真HelloWorld vcpkg installtests vcpkg install osgEarth安装指南 https://docs.osgearth.org/en/latest/install.html&#xff0c; 预先设置ports/osg/portfile.cmake GL3 否则调用osg相关功能时会出现如下提示 OpenSceneGraph does not define OSG_GL3_AVAILABLE; …

语音方向精典论文品读_HuBERT

英文名称: HuBERT: Self-Supervised Speech Representation Learning by Masked Prediction of Hidden Units 中文名称: HuBERT&#xff1a;通过隐藏单元的屏蔽预测进行自监督语音表示学习 链接: http://arxiv.org/abs/2106.07447v1 代码: https:// github.com/pytorch/fairseq…

vertica10.0.0单点安装_ubuntu18.04

ubuntu的软件包格式为deb&#xff0c;而rpm格式的包归属于红帽子Red Hat。 由于项目一直用的vertica-9.3.1-4.x86_64.RHEL6.rpm&#xff0c;未进行其他版本适配&#xff0c;而官网又下载不到vertica-9.3.1-4.x86_64.deb&#xff0c;尝试通过alian命令将rpm转成deb&#xff0c;但…

盘古信息IMS OS 数垒制造操作系统+ 产品及生态部正式营运

启新址吉祥如意&#xff0c;登高楼再谱新篇。2024年1月22日&#xff0c;广东盘古信息科技股份有限公司新办公楼层正式投入使用并举行了揭牌仪式&#xff0c;以崭新的面貌、奋进的姿态开启全新篇章。 盘古信息总部位于东莞市南信产业园&#xff0c;现根据公司战略发展需求、赋能…

交叉熵损失函数求导与Softmax函数求导

交叉熵损失函数求导与Softmax函数求导 前情提要 交叉熵损失函数 对Softmax函数求导 对交叉熵损失函数求导 前情提要 在做单分类的时候&#xff0c;一般模型的最后一层是线性层Linear做分类器&#xff0c;输出在每个标签上的logits。损失函数为交叉熵损失函数&#xff0c;会…

redis过期事件监听、可以做延时任务 第二篇(简单)

在使用redis时&#xff0c;所有的key都要设置过期时间&#xff0c;过期之后&#xff0c;redis就会把对应的key清除掉。 此方法可以监听redis的key失效&#xff0c;在失效时做一些逻辑处理 redis过期监听 不像mq有保证 不推荐用来弄需要有保证的业务 现象&#xff1a; redis …

AWS 专题学习 P12 (CloudWatch、CloudTrail、AWS Config)

文章目录 专题总览1. CloudWatch1.1 Amazon CloudWatch Metrics1.2 CloudWatch Metric Streams1.3 CloudWatch LogsCloudWatch Logs - SourcesCloudWatch Logs Metric Filter & InsightsCloudWatch Logs – S3 ExportCloudWatch Logs SubscriptionsCloudWatch Logs Aggrega…

MATLAB|【完全复现】含可再生能源和储能的区域微电网的最优运行(考虑鲁棒性和不确定性)【多阶段鲁棒调度模型】

目录 主要内容 模型研究 一、区域微网模型 二、模型优化流程​ 结果一览 下载链接 主要内容 该程序实现了一种基于可再生能源和储能的区域微电网的多阶段优化调度方法&#xff0c;该方法可以同时保证优化调度方案的鲁棒性和非预测性。模型考虑两类不确定性&…

【报错处理】ModuleNotFoundError: No module named ‘paddle.fluid‘

引言 在使用 UIE&#xff08;统一信息提取&#xff09;模型时&#xff0c;您可能会遇到错误消息 "ModuleNotFoundError: No module named paddle.fluid"。这个错误可能让人沮丧&#xff0c;但通常很容易解决。在本博客文章中&#xff0c;我将为您介绍解决此问题。 一…

卡顿监控方法

android业界各家卡顿检测工具不同&#xff0c;主要分几类&#xff1a; 注册printer callback 注册Choreographer callback MessageQueue插入空Message 字节码插桩 产品原理注册printer callback BlockCanary、BlockCanaryEx、ArgusAPM&#xff08;360&#xff09; 监听每一…

MySQL索引类型及数据结构【笔记】

1 索引类型 返回面试宝典 主键索引&#xff08;PRIMARY&#xff09;:数据列不允许重复&#xff0c;不允许为NULL&#xff0c;一个表只能有一个主键。 唯一索引&#xff08;UNIQUE&#xff09;:数据列不允许重复&#xff0c;允许为NULL&#xff0c;一个表允许多个列创建唯一索引…

C++常用总结

1、提高cin与cout效率 cin与cout效率相比于scanf与printf低下 解决方案&#xff1a; ios:sync_with_stdio(false); cin.tie(0),cout.tie(0); 2、C标准算法库algorithm max(a,b)&#xff1a;求两个数最大值min(a,b)&#xff1a;求两个数最小值abs(a,b)&#xff1a;求一个整…

AssertionError: Torch not compiled with CUDA enabled

目录 报错查看已安装的torch的版本卸载安装GPU版本的torch查看cuda版本手工安装通过pip命令手工安装。 结果更新cuda到12.1大功告成 报错 经查阅&#xff0c;这个问题是因为conda默认安装的是CPU版本的torch&#xff0c;应该使用GPU版本的。 查看已安装的torch的版本 pip li…