哈工大计算机系统实验六——高速缓冲器模拟
实验报告
实 验(六)
题 目 Cachelab
高速缓冲器模拟
专 业 xxxx
学 号 xxxx
班 级 xxxx
学 生 xxxx
指 导 教 师 xxxx
实 验 地 点 G712
实 验 日 期 2019.12.7
计算机科学与技术学院
目 录
第1章 实验基本信息............................................................................................. - 3 -
1.1 实验目的......................................................................................................... - 3 -
1.2 实验环境与工具............................................................................................. - 3 -
1.2.1 硬件环境................................................................................................. - 3 -
1.2.2 软件环境................................................................................................. - 3 -
1.2.3 开发工具................................................................................................. - 3 -
1.3 实验预习......................................................................................................... - 3 -
第2章 实验预习..................................................................................................... - 4 -
2.1 画出存储器层级结构,标识容量价格速度等指标变化(5分).............. - 4 -
2.2用CPUZ等查看你的计算机Cache各参数,写出各级Cache的C S E B s e b(5分)........................................................................................................... - 4 -
2.3写出各类Cache的读策略与写策略(5分)............................................. - 4 -
2.4 写出用gprof进行性能分析的方法(5分).............................................. - 4 -
2.5写出用Valgrind进行性能分析的方法((5分)...................................... - 4 -
第3章 Cache模拟与测试................................................................................. - 5 -
3.1 Cache模拟器设计......................................................................................... - 5 -
3.2 矩阵转置设计................................................................................................. - 5 -
第4章 总结............................................................................................................. - 6 -
4.1 请总结本次实验的收获................................................................................. - 6 -
4.2 请给出对本次实验内容的建议..................................................................... - 6 -
参考文献................................................................................................................... - 7 -
第1章 实验基本信息
1.1 实验目的
掌握Cache的功能结构与访问控制策略
培养Linux下的性能测试方法与技巧
深入理解Cache组成结构对C程序性能的影响
1.2 实验环境与工具
1.2.1 硬件环境
X64 CPU;2GHz;2G RAM;256GHD Disk 以上
1.2.2 软件环境
Windows7 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位;
1.2.3 开发工具
Visual Studio 2010 64位以上;TestStudio;Gprof;Valgrind等
了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。
用CPUZ等查看你的计算机Cache各参数,写出C S E B s e b
第2章 实验预习
2.1 画出存储器层级结构,标识容量价格速度等指标变化(5分)
2.2用CPUZ等查看你的计算机Cache各参数,写出各级Cache的C S E B s e b(5分)
三级指令缓存: 9MB 12 64 12288 log12 6
2.3写出各类Cache的读策略与写策略(5分)
1:缓存命中,则从cache中读相应数据到CPU或上一级cache中。
2:缓存不命中,则从主存或下一级cache中读取数据,并替换出一行数据。
当CPU写Cache命中时,只修改Cache的内容,而不是立即写入主存;只有当此块被换出时才写回主存。
立即将一个已经缓存了的字w的高速缓存块写回到紧接着的第一层中。。
2.4 写出用gprof进行性能分析的方法(5分)
2.5写出用Valgrind进行性能分析的方法(5分)
--version 显示valgrind内核的版本,每个工具都有各自的 版本
--tool= [default: memcheck] 最常用的选项。运行valgrind中名为toolname 的工具。如果省略工具名,默认运行memcheck。
--db-attach= [default: no] 绑定到调试器上,便于调试错误。
第3章 Cache模拟与测试
3.1 Cache模拟器设计
/*csim.c 源代码*/
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include "cachelab.h"
//#define DEBUG_ON
#define ADDRESS_LENGTH 64/* Type: Memory address */
typedef unsigned long long int mem_addr_t;
/* Type: Cache lineLRU is a counter used to implement LRU replacement policy */
typedef struct cache_line {char valid; //有效位mem_addr_t tag; //标识位int lru; //最后的访问时间距离现在最远的块
} cache_line_t;
typedef struct
{cache_line_t *lines;
}cache_set_t; //储存每一组包含的行
typedef struct
{cache_set_t *sets; //cache的空间,模拟cache
}cache_t;/* Globals set by command line args */
int verbosity = 0; /* print trace if set */
int s = 0; /* set index bits */
int b = 0; /* block offset bits */
int E = 0; /* associativity */
char* trace_file = NULL;
/* Derived from command line args */
int S; /* number of sets */
int B; /* block size (bytes) */
/* Counters used to record cache statistics */
int miss_count = 0;
int hit_count = 0;
int eviction_count = 0;
unsigned long long int lru_counter = 1;
/* The cache we are simulating */
cache_t cache;
mem_addr_t set_index_mask; //组索引掩码
mem_addr_t tag_mask; //地址标记
/** initCache - Allocate memory, write 0's for valid and tag and LRU* also computes the set_index_maskinitCache - 分配内存,写0表示有效和标记和LRU ,计算set_index_mask*/void initCache()
{int i,j;if(s<0){printf("error!\n");exit(0);}cache.sets = (cache_set_t*)malloc(S*sizeof(cache_set_t));//为组申请空间if(!cache.sets){printf("No set memory!\n");exit(0);}for(i=0;i<S;i++){cache.sets[i].lines = (cache_line_t*)malloc(E*sizeof(cache_line_t));//为行申请空间if(!cache.sets){printf("No line memory!\n");exit(0);}for(j=0;j<E;j++){cache.sets[i].lines[j].lru=0;cache.sets[i].lines[j].tag=0;cache.sets[i].lines[j].valid=0;}}}/** freeCache - free allocated memory*/void freeCache(){int i;for(i=0;i<S;i++){free(cache.sets[i].lines);}free(cache.sets);}/** accessData - Access data at memory address addr.* If it is already in cache, increast hit_count* If it is not in cache, bring it in cache, increase miss count.* Also increase eviction_count if a line is evicted.accessData - 访问内存地址addr的数据。*如果它已经在缓存中,则增加hit_count*如果它不在缓存中,请将其放入缓存中,增加错过次数。*如果一条线被驱逐,也会增加eviction_count*/void accessData(mem_addr_t addr){int i, isfull, j ,k , flag , minlru;isfull=1;for(i=0;i<E;i++){if(cache.sets[set_index_mask].lines[i].valid==1\&&cache.sets[set_index_mask].lines[i].tag==tag_mask){hit_count++;cache.sets[set_index_mask].lines[i].lru=lru_counter;for(k=0;k<E;k++){if(k!=i)cache.sets[set_index_mask].lines[k].lru--;}return;}}miss_count++;for(i=0;i<E;i++){if(cache.sets[set_index_mask].lines[i].valid==0){isfull=0;break;}}if(isfull==0) //未满{cache.sets[set_index_mask].lines[i].valid=1;cache.sets[set_index_mask].lines[i].tag=tag_mask;cache.sets[set_index_mask].lines[i].lru=lru_counter;for(k=0;k<E;k++){if(k!=i)cache.sets[set_index_mask].lines[k].lru--;}}else{eviction_count++;flag = 0;minlru = cache.sets[set_index_mask].lines[0].lru;for(j=0;j<E;j++){if(minlru>cache.sets[set_index_mask].lines[j].lru){minlru = cache.sets[set_index_mask].lines[j].lru;flag = j;}}cache.sets[set_index_mask].lines[flag].valid=1;cache.sets[set_index_mask].lines[flag].tag = tag_mask;cache.sets[set_index_mask].lines[flag].lru=lru_counter;for(k=0;k<E;k++){if(k!=flag)cache.sets[set_index_mask].lines[k].lru--;}}}/** replayTrace - replays the given trace file against the cachereplayTrace - 针对缓存重放给定的跟踪文件*/void replayTrace(char* trace_fn){char buf[1000];mem_addr_t addr=0;tag_mask=0;unsigned int len=0;FILE* trace_fp = fopen(trace_fn, "r");if(!trace_fp){fprintf(stderr, "%s: %s\n", trace_fn, strerror(errno));exit(1);}while( fgets(buf, 1000, trace_fp) != NULL) {if(buf[1]=='S' || buf[1]=='L' || buf[1]=='M') {sscanf(buf+3, "%llx,%u", &addr, &len);set_index_mask =(addr>>b)&((1<<s)-1); //组索引tag_mask = (addr>>b)>>s; //标记if(verbosity) //赘言printf("%c %llx,%u ", buf[1], addr, len);accessData(addr);/* If the instruction is R/W then access again */if(buf[1]=='M')accessData(addr);if (verbosity) //赘言printf("\n");}}fclose(trace_fp);}/** printUsage - Print usage info*/void printUsage(char* argv[])
{printf("Usage: %s [-hv] -s <num> -E <num> -b <num> -t <file>\n", argv[0]);printf("Options:\n");printf(" -h Print this help message.\n");printf(" -v Optional verbose flag.\n");printf(" -s <num> Number of set index bits.\n");printf(" -E <num> Number of lines per set.\n");printf(" -b <num> Number of block offset bits.\n");printf(" -t <file> Trace file.\n");printf("\nExamples:\n");printf(" linux> %s -s 4 -E 1 -b 4 -t traces/yi.trace\n", argv[0]);printf(" linux> %s -v -s 8 -E 2 -b 4 -t traces/yi.trace\n", argv[0]);exit(0);}
/** main - Main routine*/int main(int argc, char* argv[])
{char c;while( (c=getopt(argc,argv,"s:E:b:t:vh")) != -1){switch(c){case 's':s = atoi(optarg);break;case 'E':E = atoi(optarg);break;case 'b':b = atoi(optarg);break;case 't':trace_file = optarg;break;case 'v':verbosity = 1;break;case 'h':printUsage(argv);exit(0);default:printUsage(argv);exit(1);}}/* Make sure that all required command line args were specified确保指定了所有必需的命令行参数 */if (s == 0 || E == 0 || b == 0 || trace_file == NULL) {printf("%s: Missing required command line argument\n", argv[0]);printUsage(argv);exit(1);}/* Compute S, E and B from command line args从命令行参数计算S,E和B. */S = 1<<s; //组数B = 1<<b; //块大小E = E;/* Initialize cache */initCache();replayTrace(trace_file);/* Free allocated memory */freeCache();/* Output the hit and miss statistics for the autograder */printSummary(hit_count, miss_count, eviction_count);return 0;}
通过ppt可知,我们需要编写一个cache模拟器,该模拟器可以模拟在一系列的数据访问中cache的命中、不命中与牺牲行的情况,其中,需要牺牲行时,用LRU替换策略进行替换。
Usage: ./csim-ref [-hv] -s <s> -E <E> -b <b> -t <tracefile>
这五个文件就是用于测试csim.c的输入文件,各个文件中包含了各种不同指令,用于测试hits、missses、evictons。
每个“I”前面都没有空格。每个“M”,“L”和“S”之前总是有空格。
意思就是valgrind运行地时候第一个指令总是为操作‘I’。
②对于‘L’以及‘S’指定的操作,我们简单地可以认为这两个操作都是对某一个地址寄存器进行访问(读取或者存入数据);
③对于‘M’指定的操作,可以看作是对于同一地址连续进行‘L‘和’S‘操作。
0x10=0000...00010000,偏移值为最低四位,故S=1;
虽然操作①使得第一组(只有一行有效),但是这里的标志位的值Tag为1
cache.sets = (cache_set_t*)malloc(S*sizeof(cache_set_t));
cache.sets = (cache_set_t*)malloc(S*sizeof(cache_set_t));//为组申请空间
cache.sets[i].lines = (cache_line_t*)malloc(E*sizeof(cache_line_t));//为行申请空间
set_index_mask =(addr>>b)&((1<<s)-1); //组索引
(4)accessData - 访问内存地址addr的数据。
在函数中实现时,hit发生的情况:组索引找到的某一组,存在一行有效位为1,并且标记匹配。
再看是否驱逐,驱逐发生的情况为:组索引找到的某一组,有效位全部为1,此时发生evictions++ ,并且找到lru最小的那一行,驱逐。
另外,每次发生hit 或者只miss或者miss加上eviction ,都需要更新那一行的lru数值,具体的就是该行的lru取到最大,其他所有行的lru减一即可
注:每个用例的每一指标5分(最后一个用例10)——与参考csim-ref模拟器输出指标相同则判为正确
3.2 矩阵转置设计
/* * trans.c - Matrix transpose B = A^T** Each transpose function must have a prototype of the form:* void trans(int M, int N, int A[N][M], int B[M][N]);** A transpose function is evaluated by counting the number of misses* on a 1KB direct mapped cache with a block size of 32 bytes.*/
#include <stdio.h>
#include "cachelab.h"int is_transpose(int M, int N, int A[N][M], int B[M][N]);/* * transpose_submit - This is the solution transpose function that you* will be graded on for Part B of the assignment. Do not change* the description string "Transpose submission", as the driver* searches for that string to identify the transpose function to* be graded. */
char transpose_submit_desc[] = "Transpose submission";
void transpose_submit(int M, int N, int A[N][M], int B[M][N])
{ int i,j,k,p,t0,t1,t2,t3,t4,t5,t6,t7,t8;if(M==32&&N==32){for(i=0;i<M;i=i+8){for(j=0;j<N;j++){t1 = A[j][i];t2 = A[j][i+1];t3 = A[j][i+2];t4 = A[j][i+3];t5 = A[j][i+4];t6 = A[j][i+5];t7 = A[j][i+6];t8 = A[j][i+7];B[i][j] = t1;B[i+1][j] = t2;B[i+2][j] = t3;B[i+3][j] = t4;B[i+4][j] = t5;B[i+5][j] = t6;B[i+6][j] = t7;B[i+7][j] = t8;}}}for(i=0;i<64;i+=8){for(j=0;j<64;j+=8){for(k=j;k<j+4;k++){t0=A[k][i];t1=A[k][i+1];t2=A[k][i+2];t3=A[k][i+3];t4=A[k][i+4];t5=A[k][i+5];t6=A[k][i+6];t7=A[k][i+7];B[i][k]=t0;B[i][k+4]=t4;B[i+1][k]=t1;B[i+1][k+4]=t5;B[i+2][k]=t2;B[i+2][k+4]=t6;B[i+3][k]=t3;B[i+3][k+4]=t7;}for(k=i;k<i+4;k++){t0=B[k][j+4];t1=B[k][j+5];t2=B[k][j+6];t3=B[k][j+7];t4=A[j+4][k];t5=A[j+5][k];t6=A[j+6][k];t7=A[j+7][k];B[k][j+4]=t4;B[k][j+5]=t5;B[k][j+6]=t6;B[k][j+7]=t7;B[k+4][j]=t0;B[k+4][j+1]=t1;B[k+4][j+2]=t2;B[k+4][j+3]=t3; }for(k=i+4;k<i+8;k++){t0=A[j+4][k];t1=A[j+5][k];t2=A[j+6][k];t3=A[j+7][k];B[k][j+4]=t0;B[k][j+5]=t1;B[k][j+6]=t2;B[k][j+7]=t3;}}}if(M==61&&N==67){for(i=0;i<N;i=i+17){for(j=0;j<M;j=j+17){for(k=i;k<i+17 && k<N;k++){for(p=j;p<j+17 && p<M;p++){t1 = A[k][p];B[p][k] = t1;}}}}}}
/* * You can define additional transpose functions below. We've defined* a simple one below to help you get started. */ /* * trans - A simple baseline transpose function, not optimized for the cache.*/
char trans_desc[] = "Simple row-wise scan transpose";
void trans(int M, int N, int A[N][M], int B[M][N])
{int i, j, tmp;for (i = 0; i < N; i++) {for (j = 0; j < M; j++) {tmp = A[i][j];B[j][i] = tmp;}} }/** registerFunctions - This function registers your transpose* functions with the driver. At runtime, the driver will* evaluate each of the registered functions and summarize their* performance. This is a handy way to experiment with different* transpose strategies.*/
void registerFunctions()
{/* Register your solution function */registerTransFunction(transpose_submit, transpose_submit_desc); /* Register any additional transpose functions */registerTransFunction(trans, trans_desc); }/* * is_transpose - This helper function checks if B is the transpose of* A. You can check the correctness of your transpose by calling* it before returning from the transpose function.*/
int is_transpose(int M, int N, int A[N][M], int B[M][N])
{int i, j;for (i = 0; i < N; i++) {for (j = 0; j < M; ++j) {if (A[i][j] != B[j][i]) {return 0;}}}return 1;
}
①编写一个实现矩阵转置的函数。即对于给定的矩阵A[N][M],得到矩阵B[M][N],使得对于任意0<=i<N、0<=j<M,有B[j][i]=A[i][j],
并且使函数调用过程中对cache的不命中数miss尽可能少。
char transpose_submit_desc[] = "Transpose submission";
void transpose_submit(int M, int N, int A[N][M], int B[M][N]);
第4章 总结
4.1 请总结本次实验的收获
以后会充分考虑Cache的功能结构来书写程序,减少Cache不命中的次数。
4.2 请给出对本次实验内容的建议
参考文献
[1] 林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42.
[2] 辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[4] 谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5] KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
哈工大计算机系统实验六——高速缓冲器模拟相关推荐
- Cachelab 高速缓冲器模拟
实验报告 实 验(六) 题 目 Cachelab 高速缓冲器模拟 专 业 计算机科学与技术 csim.c和trans.c代码见文章末尾 目 录 第1章 实验基本信息... - 3 ...
- 计算机系统实验六:程序的链接
参考教材:计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162 ...
- 哈工大计算机系统实验二——DataLab数据表示
计算机系统实验二特别难,和上一届的实验不一样,没有学长的火炬,当时做的时候特别崩溃.幸好有一帮志同道合的伙伴们,一起慢慢把实验解决了. 把火炬传下去! 实验报告 实 验(二) 题 目 Data ...
- 哈工大计算机系统实验一:计算机系统漫游
计算机系统实验一:计算机系统漫游 寒假直接copy文档上传,有错误很正常(有对不上的地方请私聊我改正一下) 把火炬传下去把! 实验报告 实 验(一) 题 目 计算机系统漫游 专 业 ...
- 哈工大计算机系统实验七——微壳
实验报告 实 验(七) 题 目 TinyShell 微壳 专 业 计算机类 学 号 xxxx 班 级 xxxx 学 生 xxxx 指 导 教 师 xxxx ...
- 哈工大计算机系统实验四——链接
链接这一块呢,先看了李春凤老师的慕课,然后看一遍课本,然后来做实验,感觉真的懂了一样 把火炬传下去! 实验报告 实 验(四 题 目 LinkLab 链接 专 业 xxxx 学 ...
- S7-1200PLC—实验六 四节传送带控制模拟
实验六 四节传送带控制模拟 一.实验目的 应用PLC的定时器.置位.复位等基本控制指令,根据控制要求,设计四节传送带控制系统. 二.PLC介绍 PLC (可编程逻辑控制器)是工业控制的核心部件,以控制 ...
- 操作系统课程设计---实验六 银行家算法的模拟与实现
实验六 银行家算法的模拟与实现 完整课程设计源码及其报告查看:陈陈的操作系统课程设计 1.实验目的 (1) 进一步理解进程的并发执行. (2) 加强对进程死锁的理解,理解安全状态与不安全状态的概念. ...
- 【2022】哈工大计算机系统大作业——程序人生Hello’s P2P
2022哈工大计算机系统大作业--程序人生Hello's P2P 摘要 第1章 概述 1.1 Hello简介 1.2 环境与工具 1.3 中间结果 1.4 本章小结 第2章 预处理 2.1 预处理的概 ...
最新文章
- 计算机应用基础 辅助教学系统,计算机应用基础课程辅助教学和智能测评系统使用手册——网络版.doc...
- Python删除文件及进行文件夹压缩
- HTML5中figure标签使用实例
- SQL SERVER 2005无法远程连接的问题
- struts2 mysql 分页代码_Struts2 + MySQL 实现分页
- 单片机里面的CPU使用率是什么鬼?
- Python之路 day1 基础1 变量 for while 用户输入
- openssh升级之后git账户免密登陆失效
- python爬虫的用途_python爬虫用代理ip有什么用途?
- 小学四年级计算机教案清华出版,清华版四年级下册信息技术电子备课教案
- matlab潮流计算ppt,matlab潮流计算.doc
- 进栈顺序为abcd则出栈顺序为_进栈顺序为ABCDEFG 有可能的出站顺序是什么
- 候选键的计算(数据库系统概论)
- 程序员工资真的很高么,月入几万的难道不是吹牛?
- 从2T-12.8T 一颗芯片全搞定
- BigDecimal舍入模式(Rounding Modes)
- 简单的封装知识 RDL,TSV, Bump,Wafer
- python pandas str列内置方法
- 计算机卸载一个程序正确操作,电脑这两个操作要学会,两种卸载软件的方法,保证电脑系统稳定...
- 收集前端优秀的网站、博客、书籍
热门文章
- ASO第一步-什么是ASO,与SEO的区别?
- Broadcom 802.11n网络适配器,网络连接没有有效的ip配置问题解决
- 日式键盘与美式键盘转换
- 如何修复Windows 10中的声音问题
- [总结]高效能人士的七个习惯
- 数学基础_设随机变量X1,X2,…Xn相互独立,且都服从(0,θ)上的均匀分布。求U=max{X1,X2,…Xn}数学期望
- 【无人驾驶系列五】GPS及惯性传感器在无人驾驶中的应用
- libusb系列-002-Windows下libusb源码编译
- wps中删除我的设备(已经不使用的)
- Java语言中 void和public void的区别,static和public static的区别。