首页 > 其他分享 >计算机系统基础实训五—CacheLab实验

计算机系统基础实训五—CacheLab实验

时间:2024-06-22 17:00:40浏览次数:24  
标签:计算机系统 缓存 函数 转置 cache 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几乎完全为空,你需要从头开始写。

第一部分的注意事项:

  1. 你的csim.c文件必须在没有警告的情况下通过编译才能获得分数。

你的模拟器必须在任意的s、E和b下都能正常工作。这意味着你需要使用malloc函数为模拟器的数据结构分配空间。malloc函数的使用方法自己百度。

  1. 对于这个实验中,我们只对数据缓存性能感兴趣,所以您的模拟器应该忽略所有指令缓存访问(以“I”开头的行)。“I”总是顶格的,它前面没有空格,而“M”、“L”和“S”前面有空格,可以根据这一点来区分。
  2. 要获得第一部分的分数,必须在main()函数结束前调用函数printsummmary()来输出命中、未命中和驱逐的数量。
  3. 对于这部分,您应该假设内存访问已正确对齐,因此内存访问永远不会跨越块边界。通过这个假设,你可以忽略在内存访问轨迹文件中的“大小”字段。

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

  1. 最多使用12 local variables int。不能作弊。
  2. 不可递归。
  3. 用helper函数的话,栈总共不超12 variables
  4. A不许修改。
  5. 不允许用数组和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次)。虽然这个实验看上去不难,但是我还是需要借助一定的资源完成该实训。

标签:计算机系统,缓存,函数,转置,cache,CacheLab,实训,命中,模拟器
From: https://blog.csdn.net/zyx210603/article/details/139883862

相关文章

  • [本科项目实训] 行动模拟实现 与 FastAPI 对应交互-V0
    to2024/06/01行动模拟该项目拟通过大语言模型分析拆解人类描述的任务,自动的调用行动库进行执行并完成内容的汇报。因而需要针对任务对大模型进行微调(比如本项目使用的p-tuningv2),行动模拟即针对微调结果将大模型与行动库进行对接,模拟实际场景下的函数输入输出。第一步,即加......
  • 头歌机器学习实训答案 第1关:集成学习常用算法详解
    任务描述本关任务:学习集成学习的基本概念以及常用算法并编程熟悉sklearn。相关知识为了完成本关任务,你需要掌握:1.个体与集成的概念,2.常用的集成学习算法。个体和集成集成学习(ensemblelearning)通过构建并结合多个学习器来完成学习任务,有时也被称为多分类器系统(multi-class......
  • 《深入理解计算机系统》
    深入理解计算机系统读书先看书之序言:明确他面向的读者——本书是一个导论课本,是面向程序员的,所以并不是那么深入(因为程序员也不需要了解那么多)所以这对于初学者来说是比较容易的,合适的入门之选第一章:计算机系统漫游相当于是一个粗略的介绍,导言,但是短小精干1.1信息就是位+......
  • Java计算机毕业设计+Vue实习实训管理系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在当今社会,实习实训已成为高等教育中不可或缺的一部分,对于学生实践能力和职业素养的提升具有重要意义。然而,传统的实习实训管理方式存在着诸多不便,如......
  • 实训日记十:Python文本挖掘数据分析-part1
    目录数据分析流程项目背景&产品架构数据说明分析流程加载数据清洗数据-驱虫市场潜力分析整体市场-驱虫市场的潜力分析数据分析流程每个环节都有具体的要求,例如需求文档要求包含:目的,分析思路,预期效果业务部门出问题和需求,以及对算法&数据部门输出报告的理解和......
  • Javaweb实训太难不会做,哪里有代做Javaweb实训的?
    需要代做请发布需求**要接单:https://www.yaojiedan.com**理解基本概念:深入研究Web开发的基础,包括网络协议、Web应用的生命周期、MVC(模型-视图-控制器)架构模式等。理解浏览器和服务器之间的通信是如何进行的,以及它们是如何通过HTML、CSS和JavaScript进行交互的。学习......
  • Unity制作透明材质直接方法——6.15山大软院项目实训
    之前没有在unity里面接触过材质的问题,一般都是在maya或这是其他建模软件里面直接得到编辑好材质的模型,然后将他导入Unity里面,然后现在碰到了需要自己在Unity制作透明材质的情况,所以先搜索了一下有没有现成的方法,很多博客都是使用自己手搓shader的方法,如果对于透明材质的投射折......
  • JSON响应中提取特定的信息——6.14山大软院项目实训2
    在收到的JSON响应中提取特定的信息(如response字段中的文本)并进行输出,需要进行JSON解析。在Unity中,可以使用JsonUtility进行简单的解析,但由于JsonUtility对嵌套对象的支持有限,通常推荐使用第三方库如Newtonsoft.Json来处理复杂的JSON结构。首先,确保Unity项目中已经包含了Newton......
  • Unity中使用UI组件实现场景切换——6.18山大软院项目实训
    设置场景切换在Unity项目中,首先需要准备几个场景,并在项目的“BuildSettings”中添加这些场景,以确保SceneManager可以加载它们。本例中,我们假设已有几个场景编号依次为1到5。脚本概述我们创建了一个SwitchScene类,这个类包含了几个公共方法,允许通过不同方式切换场景:使用下拉......
  • 简单处理字符串——6.14山大软院项目实训1
    对于直接输出服务器返回的json到Debug,发现他还包含json的结构,但是不想调试json的返回结构,可以使用简单地处理字符串的方法,而不引入额外的库或复杂的JSON解析,但是这个解决方式是暂时的是投机取巧的,正确的做法我会在下一条博客里面写出来。可以考虑使用字符串操作方法直接从接收......