计算机系统基础实训五—CacheLab实验
实验目的与要求
1、让学生更好地应用程序性能的优化方法;
2、让学生更好地理解存储器层次结构在程序运行过程中所起的重要作用;
3、让学生更好地理解高速缓存对程序性能的影响;
实验原理与内容
本实验将帮助您了解缓存对C程序性能的影响。实验由两部分组成。在第一部分中,您将编写一个模拟高速缓存行为的小型C程序(大约200-300行)。在第二部分中,您将优化一个小的矩阵转置函数,目标是最小化缓存未命中的数量。
1、第一部分:编写缓存模拟器
cachelab-handout/traces子目录包含一组内存引用轨迹文件,这些文件将用于评估您在第一部分中编写的缓存模拟器的正确性。内存引用轨迹文件由Linux程序valgrind生成,具有如下格式:
I 0400d7d4,8
M 0421c7f0,4
L 04f6b868,8
S 7ff0005c8,8
每行表示一次或两次内存访问,每一行的格式如下:
[空格]操作地址,大小
操作字段表示内存访问的类型:“I”表示指令加载,“L”表示数据加载,“S”表示数据存储,“M”表示数据修改(即,数据加载+数据存储)。在每个“I”的前面是没有空格的,在每个“M”、“L”和“S”的前面都有一个空格。“操作地址”字段代表一个64位十六进制内存地址。“大小”字段指定对应操作所访问的字节数。
在第一部分中,您将编辑csim.c文件,实现一个缓存模拟器。它以valgrind的内存引用轨迹文件作为输入,模拟缓存的命中和未命中行为,并输出命中、未命中和逐出的数量。
我们为您提供了一个名为csim-ref的标准的缓存模拟器的二进制可执行文件,该模拟器模拟具有任意大小和相联度的缓存的行为。在选择要逐出的缓存行时,它使用LRU替换策略,这个参考模拟器就是标准答案,它可以接收以下命令行参数:
./csim-ref [-hv] -s <s> -E <E> -b <b> -t <tracefile>
-h: 可选参数,用于输出使用帮助
-v:可选参数,用于输出跟踪信息的详细内容
-s <s>:设置组索引位的数量(组数量S=2s)
-E <E>:设置每组的行数
-b <b>:设置块大小(块大小B=2b位)
-t <tracefile>:要跟踪的内存引用轨迹文件的名称
命令行参数基于教科书第六章的符号(s、E和b),例如执行指令“./csim-ref -s 4 -E 1 -b 4 -t traces/yi.trace”将输出“yi.trace”内存引用轨迹文件在标准缓存模拟器(s=4,E=1,b=4)中的缓存使用情况:
第一部分的工作是要编辑csim.c文件,以使它使用与csim-ref相同的命令行参数和产生与它相同的输出。请注意,拿到手上的csim.c几乎完全为空,你需要从头开始写。
第一部分的注意事项:
- 你的csim.c文件必须在没有警告的情况下通过编译才能获得分数。
你的模拟器必须在任意的s、E和b下都能正常工作。这意味着你需要使用malloc函数为模拟器的数据结构分配空间。malloc函数的使用方法自己百度。
- 对于这个实验中,我们只对数据缓存性能感兴趣,所以您的模拟器应该忽略所有指令缓存访问(以“I”开头的行)。“I”总是顶格的,它前面没有空格,而“M”、“L”和“S”前面有空格,可以根据这一点来区分。
- 要获得第一部分的分数,必须在main()函数结束前调用函数printsummmary()来输出命中、未命中和驱逐的数量。
- 对于这部分,您应该假设内存访问已正确对齐,因此内存访问永远不会跨越块边界。通过这个假设,你可以忽略在内存访问轨迹文件中的“大小”字段。
2、第二部分:优化矩阵转置
在第二部分中,你将编辑trans.c文件实现一个转置函数,目标是使得在程序运行过程中尽可能少的发生缓存未命中。
如果A表示一个矩阵,则矩阵A的转置矩阵为AT,它们之间的关系为:Aij=ATji
为了帮助您编程,我们在trans.c中为您提供转置函数示例,该示例计算N×M矩阵A的转置,并将结果存储在M×N矩阵B中。该示例的转置函数是正确的,但它效率低下,因为访问模式导致许多缓存未命中。
在第二部分中,您的工作是编写一个类似的函数,称为transpose_submit,以缓存未命中最少化的方式实现矩阵转置。
第二部分注意事项:
1)你的trans.c文件必须在没有警告的情况下通过编译才能获得分数。
2)每个转置函数最多可以定义12个int类型的局部变量。
3)不允许通过使用long类型的变量或使用位技巧将多个值存储到单个变量这种手段来规避2)中的限制。
4)转置函数不能使用递归。
5)如果使用函数调用,在被调用函数和顶层转置函数之间的栈空间上的局部变量不得超过12个。例如,如果你的转置函数声明8个变量,然后在转置函数里调用了一个使用4个变量的函数,该函数再调用另一个包含2个局部变量的函数,则栈空间上将有14个变量,这将违反规则。
6)您的转置函数不能修改数组A,但是您可以修改数组B。
不允许在代码中定义任何数组或使用malloc之类的函数。
实验设备与软件环境
1.Linux操作系统—64位 Ubuntu 18.04
2. C编译环境(gcc)
3. 计算机
实验过程与结果(可贴图)
1.安装valgrind,在终端命令行中运行指令“sudo apt-get install valgrind”
2.安装Python2.7,在终端命令行中运行指令“sudo apt-get install python”
3.将“cachelab-handout.tar”文件拷贝到虚拟机的某文件夹里面并在该文件夹里打开终端使用命令 “tar xvf cachelab-handout.tar”进行解压
A部分
在csim.c中完成cache模拟器的编码。自己写的程序需要输出与目标文件一样。cache使用LRU策略。先查看一下分数
查看一下dave.trace
valgrind生成的内存引用轨迹文件格式,每行代表一次或两次内存访问,包括操作类型(如"I"、"L"、"S"、"M"分别表示指令加载、数据加载、数据存储和数据修改)以及相应的64位十六进制内存地址和访问字节数。
编写代码
1.每行含有:一个有效位、t个标记位,b个高速缓存位。以及支持LRU的时间。可以定义一个struct支持。
2.根据给定的命令行参数 -s、-E 和 -b 设置缓存系统的组索引位数、每组缓存行数和块大小,可以定义一个二维数组。
完整代码如下:
27满分
B部分
在trans.c中完成矩阵转置函数transpose_submit,并且越少的Miss越好。
限制:
评估方法规则如下:
32 × 32: 满分8 分 if 未命中 < 300, 0 points if 未命中 > 600
64 × 64: 满分8 分 if 未命中 < 1, 300, 0 points if 未命中 > 2, 000
61 × 67: 满分10 分 if 命中 < 2, 000, 0 points if 未命中 > 3, 000
1、32 × 32
对于题目所给的trans()函数来说,misses数高的原因在于,对于数组A是以行来访问,而对于数组B是以列为访问,又由cahce的存储量可知,一整个cache可以存储的数组的前8行所有元素(8行填满一个cahce),而在访问数组B第九行的第1个元素之后,又会将之前存储的八行cache全部冲突替换掉,导致没有充分利用cache数据(只用到每个块的1个元素),只能重新加载之前的cache,造成大量的misses。
为了提高cache的利用率,即,在cache载入后,将cache包含的元素全部操作后再替换cache,保证不会二次载入相同的cache,即设置子块大小为 8 × 8
- 最多使用12 local variables int。不能作弊。
- 不可递归。
- 用helper函数的话,栈总共不超12 variables
- A不许修改。
- 不允许用数组和malloc.
运行结果会发现会有343次的misses,而理论上的研究则为 16 块 × 8 次 × 2 = 256 次 16块 \times 8次 \times 2 = 256次 16块×8次×2=256次,显然有很大的差距,而且满分的操作为misses < 300。再次分析trace文件就会发现数组A(0x30a080)和B(0x34a080)的起始地址所映射的cache块相同,即在数组A和B的对角块上的元素会发生冲突不命中,而且在对角块上时数组B的缓存会将刚才缓存的数组A丢弃掉,故我们只需将A中缓存的值用变量保存起来,就可以减少misses数。
显然可以看出对角块数组A和B的缓存会存在冲突
通过./csim-ref -v -s 5 -E 1 -b 5 -t trace.f0 > trace_details.f0
命令查看一下命中情况
故改进代码如下:
2、64 × 64
如果采用刚才同样的分析,可以得到子块为 8 × 4,可以保证数组B每四个cache块( 4 × 8),不会发生二次载入的情况。而对于数组A来说,四个cahce块为( 8 × 4),这样的配置会导致每一个A的cache块只有四个int数据会被利用到,而其余四个数据需要下次载入才可利用,这样的代码如下:
misses数为1651,很显然不符合满分要求。(misses < 1300)
所以为了能够充分利用cache块,我们只能在 8 × 8 8\times8 8×8的框架下具体分析操作。(将 8 × 8 8\times8 8×8分为4个 4 × 4 4\times4 4×4)
思路:为了将前文浪费的四个int数据有效利用起来,因为局部变量数目的限制,所以可以考虑将多的数据暂时放入数组B的cache中,以待后续的操作,这样就可以避免二次载入相同的cache块
① 观察以下两个对应的 8 × 8 8\times8 8×8区域。我们要将A的元素转置到B
② 将区域一的黄色区域元素转置至对应位置,将区域一的蓝色区域暂时转置存放在区域二的蓝色区域(即数组B此时cache块的右半部分)
③ 而后逐行进行后四行前四列的转置
至此这个 8 × 8 8\times8 8×8的区域全部转置完成,理论上每一块中不命中一次,即 8 块 / 行 × 64 行 × 2 = 1024 次 8块/行\times64行\times2 = 1024次 8块/行×64行×2=1024次。
3、61 × 67
此时所给的M和N对于cache块来说已经无法像前面的情况一样,可以对齐处理,如果要分析的话比较复杂,题目的满分要求也比较低misses < 2000。故采用变换分块大小来观察。
基本上 8 × 8 8\times8 8×8之后misses数在2000左右浮动,没有什么规律,在 17 × 17 17\times17 17×17时达到最小1950。
总的分数为:
实验总结
本次CacheLab实验中,我编写了缓存模拟器,模拟内存引用轨迹,遵循LRU策略,支持多参数设置,编译无警告,与标准模拟器对比验证准确。针对32×32、64×64、61×67矩阵,优化转置函数以减少缓存未命中的次数。对32×32矩阵,设8×8子块、用临时变量避免对角块冲突,未命中降为343次(满分要求<300次)。对64×64矩阵,初试8×4子块后未达标(1651次),改用4个4×4子块,优化数据访问,满足满分要求(<1300次)。虽然这个实验看上去不难,但是我还是需要借助一定的资源完成该实训。
相关文章:

计算机系统基础实训五—CacheLab实验
实验目的与要求 1、让学生更好地应用程序性能的优化方法; 2、让学生更好地理解存储器层次结构在程序运行过程中所起的重要作用; 3、让学生更好地理解高速缓存对程序性能的影响; 实验原理与内容 本实验将帮助您了解缓存对C程序性能的影响…...

PHP框架之CodeIgniter框架
CodeIgniter框架详细说明 CodeIgniter是一个简单而强大的PHP框架,专为快速开发Web应用程序而设计。它遵循MVC(模型-视图-控制器)设计模式,为开发者提供了丰富的功能和灵活性,同时保持代码的轻量级和易于管理。CodeIgn…...

714. 买卖股票的最佳时机含手续费
714. 买卖股票的最佳时机含手续费 原题链接:完成情况:解题思路:ExplanationSummary 参考代码:_714买卖股票的最佳时机含手续费 错误经验吸取 原题链接: 714. 买卖股票的最佳时机含手续费 https://leetcode.cn/probl…...

Linux系统查看程序内存及CPU占用
文章目录 1.free命令2.top命令3.PS命令3.1 查看内存占用前10位:3.2 查看CPU占用前10位 参考文档 1.free命令 可以通过free命令查看物理内存占用情况 #单位KB free #单位MB free -m #单位GB free -h 2.top命令 输入top命令,会输出定时刷新的程序PID、内…...

数据结构7---图
一、定义 对于图的定义,我们需要明确几个注意的地方:一线性表中我们把数据元素叫元素,树中叫结点,在途中数据元素我们则称之为顶点(Vertex)。 对于图的定义,我们需要明确几个注意的地方: 线性表中我们把数据元素叫元素…...

Excel 如何复制单元格而不换行
1. 打开excle, sheet1右键单击>查看代码>插入>模块 输入代码 Sub CopyText() Updated by NirmalDim xAutoWrapper As ObjectSet xAutoWrapper New DataObject or GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")xAutoWrapper.SetText ActiveC…...

前端 CSS 经典:mix-blend-mode 属性
前言:这是一个混合属性,作用是将两个颜色混合生成一个新颜色。可以将视频和文字相融合,产生动态文字效果。 效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" />&l…...

OpenCV--滤波器(一)
低通滤波器 代码和笔记 代码和笔记 import cv2 import numpy as np""" 滤波器--用于图像处理的重要工具,它们可以根据图像中像素的邻域信息来修改像素值,以实现去噪、模糊、锐化、边缘检测等效果。低通滤波器(Low-pass Filte…...

MK的前端精华笔记
文章目录 MK的前端精华笔记第一阶段:前端基础入门1、(1)、(2)、 2、3、4、5、6、7、 第二阶段:组件化与移动WebAPP开发1、(1)、(2)、 2、3、4、5、6、7、 第三…...

低代码平台框架:开源选型、实践与应用深度解析
文章目录 1.1 低代码平台的重要性与应用背景2.1 表单建模2.2 流程设计2.3 报表(打印)可视化2.4 代码生成器2.5 系统管理2.6 前端UI开源选型3.1 如何选择合适的开源框架3.2 市场上的主要开源低代码平台对比3.3 开源项目的技术栈与优缺点分析 5.1 成功案例…...

深度学习500问——Chapter12:网络搭建及训练(3)
文章目录 12.3.5 Caffe有哪些接口 12.4 网络搭建有什么原则 12.4.1 新手原则 12.4.2 深度优先原则 12.4.3 卷积核size一般为奇数 12.4.4 卷积核不是越大越好 12.5 有哪些经典的网络模型值得我们去学习的 12.6 网络训练有哪些技巧 12.6.1 合适的数据集 12.6.2 合适的预…...

Android使用DevRing框架搭建数据库实体类以及使用
一、引用DevRing依赖 //导入DevRing依赖implementation com.ljy.ring:devring:1.1.8创建数据库表的依赖implementation org.greenrobot:greendao:3.2.2 // add libraryimplementation org.greenrobot:greendao-generator:3.0.0 二、修改工程目录下的.idea->gradle.xml文件&…...

高效BUG管理:定级、分类和处理流程
高效BUG管理:定级、状态跟踪与处理全流程 前言一、BUG的定义二、BUG的定级三、BUG的状态四、BUG的处理流程1. BUG报告2. BUG确认3. BUG修复4. BUG验证5. BUG关闭 五、常见问题与解决方案六、总结 前言 在测试工作中,BUG的定级和分类是一个重要环节&…...

服务器数据恢复—raid5热备盘同步失败导致阵列崩溃如何恢复数据?
服务器存储数据恢复环境&故障: 某品牌DS5300存储,包含一个存储机头和多个磁盘柜,组建了多组RAID5磁盘阵列。 某个磁盘柜中的一组RAID5阵列由15块数据盘和1块热备硬盘组建。该磁盘柜中的某块硬盘离线,热备盘自动替换并开始同步…...

Ubuntu iso 镜像下载 步骤截图说明
Ubuntu镜像下载,在这个网址: Enterprise Open Source and Linux | Ubuntu 步骤如下图所示: 1、登入网址 2、点击Get Ubuntu 3、点击Download Ubuntu Desktop 后续点击Downloadload 24.04 LTS直接下载就行 如果需要下载其它版本…...

git拉取gitee项目到本地
git安装等不做赘述。 根据需要选择不同操作 1.只是单纯拉取个项目,没有后续的追踪等操作 不需要使用git init初始化本地文件夹 新建一个文件夹用于存储项目,右键选择 git bash here 会出现命令行窗口 如果像我一样,只是拉取个项目作业&…...

力扣42.接雨水
力扣42.接雨水 前后缀数组 对于每个一个位置 求其前面最高高度pre_max[i] max(pre_max[i-1] , h[i])和后面最高高度suf_max[i] max(suf_max[i1] , h[i])当前i处的水容量 为min(pre_max[i] , suf_max[i]) - h[i] class Solution {public:int trap(vector<int>& …...

国产数据库与MYSQL兼容性?开发应该怎么选择?
国产数据库主要包括以下几种: TiDB:由 PingCAP 公司研发设计的开源分布式 HTAP (Hybrid Transactional and Analytical Processing) 数据库,兼容 MySQL,支持无限的水平扩展,具备强一致性和高可用等特性。 华为GaussDB…...

Spring框架中Bean的生命周期
Bean的生命周期通常指的是从创建到初始化,经过一系列的流程,最终销毁的过程。只不过,在Spring框架中,Bean的生命周期是由Spring IOC容器来管理的。在Spring中,我们定义Bean时,也可以自己指定初始化和销毁的…...

从零到一学FFmpeg:avformat_alloc_output_context2 函数详析与实战
文章目录 前言一、函数原型二、功能描述三、使用场景四、AVFormatContext 结构体五、代码实例 前言 avformat_alloc_output_context2 是FFmpeg库中的一个函数,用于为输出多媒体文件初始化一个AVFormatContext结构体。这个函数在开始输出音频、视频数据到文件之前被…...

Lua 绕过元表
Lua 绕过元表,直接访问 table 的字段。 绕过元表 rawset(table, index, value),在不触发元方法的情况下,设置 table[index] 的值为 value。 rawget(table, index),在不触发元方法的情况下,获取 table[index] 的值。…...

pip方法总结(极简快速掌握)
pip是Python的包管理工具,它允许用户从PyPI等源安装和管理额外的库和依赖。以下是关于pip使用方法的详细总结,同时附上代码演示: 一、pip的基本功能 安装包:使用pip install 包名命令可以安装指定的Python包。例如,要…...

aigc基础概念(一)
目录 一、AI 1.1、基本术语 1、Artificial Intelligence (AI) —— 人工智能 2、Generative AI —— 生成性人工智能 3、Machine Learning (ML) —— 机器学习 4、Deep Learning (DL) —— 深度学习 5、Large Language Model (LLM) —— 大型语言模型 6、Transformers …...

USB学习——12、usb初始化和插拔驱动软件流程大致框架描述
usb初始化和插拔驱动软件流程大致框架描述: 当设备启动时,usb的主机控制器设备驱动(HCD)和 usb的root hub会先初始化: 1、xhci-plat.c主机控制器驱动那里,__usb_creat_hcd创建usb主机数据结构,m…...

【ARMv8/ARMv9 硬件加速系列 2.4 -- ARM NEON Q寄存器与V寄存器的关系】
文章目录 Q 与 V 的关系向量寄存器 v 的使用赋值操作寄存器赋值总结Q 与 V 的关系 在ARMv8/v9架构中,v寄存器和q寄存器实际上是对相同的物理硬件资源的不同称呼,它们都是指向ARM的SIMD(单指令多数据)向量寄存器。这些寄存器用于高效执行向量和浮点运算,特别是在多媒体处理…...

Oracle中递归查询(START WITH……CONNECT BY……)
一、基本语法 在Oracle中START WITH……CONNECT BY……一般用来查找存在父子关系的数据,也就是树形结构的数据。 SELECT * FROM TABLE WHERE 条件3 START WITH 条件1 CONNECT BY 条件2;start with [condition]:设置起点,用来限制第一层的数…...

【云原生|K8S系列】如何创建Kubernetes job和Cronjobs 入门指南
本kubernetes教程解释了如何创建kubernetes作业和cronjobs,以及它的基础知识、用例和一些提示和技巧。 什么是Kubernetes Job? Kubernetes job和cronjob是Kubernetes对象,主要用于短期和批处理工作负载。 kubernetes作业对象基本上部署了一个pod&…...

力扣每日一题 6/23 字符串/模拟
博客主页:誓则盟约系列专栏:IT竞赛 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 520.检测大写字母【简单】 题目: 我们定义,在以下…...

Google trend搜索关键词
Google trend地址:https://trends.google.com/trends/?geoUS&hlzh-CN 1、具体的操作步骤如下: 2、Google trend搜索页面如下:...

Unity C#调用Android,IOS震动功能
最近在Unity上需要很原生移动端进行交互, 原理:新建一个android项目,把生成的app module给干掉,然后留下一个vibrationPlugin module,在这个module下写android震动代码,将这个android工程构建出来的 aar移…...