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

news2025/1/18 20:25:13

实验目的与要求

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次)。虽然这个实验看上去不难,但是我还是需要借助一定的资源完成该实训。

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

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

相关文章

地推利器Xinstall:全方位二维码统计,打造高效地推策略,轻松掌握市场脉搏!

在移动互联网时代&#xff0c;地推作为一种传统的推广方式&#xff0c;依然占据着重要的地位。然而&#xff0c;随着市场竞争的加剧&#xff0c;地推也面临着诸多挑战&#xff0c;如如何有效监测下载来源、解决填码和人工登记的繁琐、避免重复打包和iOS限制、以及如何准确考核推…

安装vue时候发现npm淘宝镜像不能使用,报出:npm.taobao.org和registry.npm.taobao.or

2024.3.12 安装vue时候发现npm淘宝镜像不能使用&#xff0c;需要重新更换源&#xff0c;简单来说就是更换镜像 使用 npm config get registry 查看当前的镜像&#xff1b; npm config get registry 使用npm config set registry http://mirrors.cloud.tencent.com/npm/ &…

嵌入式实验---实验五 串口数据接收实验

一、实验目的 1、掌握STM32F103串口数据接收程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、STM32F103R6能通过查询中断方式接收数据&#xff0c;每接收到一个字节&#xff0c;立即向对方发送一个相同内容的字节&#xff0c;并把该字节的十六进…

见证数据的视觉奇迹——DataV Atlas

引言 前段时间一直沉迷于AI方向&#xff0c;几乎很久没碰大数据开发的相关内容了&#xff0c;今天突然看到阿里活动又推出DataV的体验了&#xff0c;我直接“啪”的一下就点进来了&#xff0c;很快啊&#xff01;本来之前开发数字孪生的时候就接触过基础的DataV操作了&#x…

Monica

在 《long long ago》中&#xff0c;我论述了on是一个刚出生的孩子的脐带连接在其肚子g上的形象&#xff0c;脐带就是long的字母l和字母n&#xff0c;l表脐带很长&#xff0c;n表脐带曲转冗余和连接之性&#xff0c;on表一&#xff0c;是孩子刚诞生的意思&#xff0c;o是身体&a…

Redis 的安装与部署

本文为Redis的Linux版单机部署。 上传 redis-3.2.8 源码到 /opt/software/ 解压到 /opt/module/ [huweihadoop101 software]$ tar -zxvf redis-3.2.8.tar.gz -C /opt/module/安装依赖 [huweihadoop101 software]$ sudo yum -y install gcc-c tclRedis是C语言编写的 编译安装…

文件顺序读取--函数解析

fgetc和fputc 函数 fgetc和fputc是C语言中用于文件操作的函数&#xff0c;分别用于从文件中读取字符和向文件中写入字符。以下是这两个函数的详细原型和说明&#xff1a; fgetc函数原型 int fgetc(FILE *stream);参数说明&#xff1a; FILE *stream&#xff1a;一个指向FIL…

【Linux系列】find命令使用与用法详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

淘酒屋荣获2024中法贸易杰出服务商称号暨夏季窖主大会圆满召开

淘酒屋荣获中法贸易杰出服务商称号&#xff0c;暨闪光的创始人2024夏季窖主大会圆满召开 2024年&#xff0c;作为中法建交60周年的重要节点&#xff0c;同时迎来了中法文化旅游年&#xff0c;这为两国文化交流与合作开启了新的篇章。在庆祝中法贸易交流的重要时刻&#xff0c;…

Java——集合(一)

前言: Collection集合&#xff0c;List集合 文章目录 一、Collection 集合1.1 集合和数组的区别1.2 集合框架1.3 Collection 集合常用方法1.4 Collction 集合的遍历 二、List 集合2.1 List 概述2.2 List集合的五种遍历方式2.3 List集合的实现类 一、Collection 集合 1.1 集合和…

ubuntu 18.04 server源码编译安装freeswitch 1.10.11——筑梦之路

前言 这里主要编译支持语音通话、视频通话、短信、webrtc功能的PBX。 安装编译工具包和依赖包 sudo apt-get updatesudo apt-get install -y autoconf git libtool g zlib1g-dev libjpeg-dev libcurl4-openssl-dev libspeex-dev libldns-dev libedit-dev libssl-dev pkg-con…

学校报修管理系统

摘 要 随着社会的发展和技术的进步&#xff0c;学校报修管理系统在学校设备维修工作中扮演着至关重要的角色。该系统的设计和实现对于提高学校设备维修效率、优化资源管理、提升用户体验具有重要意义。本论文基于SpringBoot框架&#xff0c;设计并实现了一套学校报修管理系统。…

DWG转PDF字体研究记录

1.前言 最近需要对PDF中的符合业务规则的文字进行提取&#xff0c;发现有些文字不是文字信息形式存储&#xff0c;而是polyline形式表达&#xff0c;意味着仅仅有形体上的表达&#xff0c;丢失了原本的文字信息。 经过沟通得知&#xff0c;这些PDF是AutoCAD软件导出的&#xf…

2-3KW户储、家储逆变器设计资料

储能电源方案双向逆变器板资料&#xff0c;原理文件&#xff0c;PCB文件&#xff0c;源代码&#xff0c;bom清单。 bom表&#xff1a; PCB&#xff1a; 变压器电感 2-3KW户储、家储逆变器设计通常需要考虑以下几个方面&#xff1a; 输入电压范围&#xff1a;逆变器需要能够适应…

数据库新技术【分布式数据库】

文章目录 第一章 概述1.1 基本概念1.1.1 分布式数据库1.1.2 数据管理的透明性1.1.3 可靠性1.1.4 分布式数据库与集中式数据库的区别 1.2 体系结构1.3 全局目录1.4 关系代数1.4.1 基操1.4.2 关系表达式1.4.3 查询树 第二章 分布式数据库的设计2.1 设计策略2.2 分布设计的目标2.3…

Apriori 处理ALLElectronics事务数据

通过Apriori算法挖掘以下事务集合的频繁项集&#xff1a; 流程图 代码 # 导入必要的库 from itertools import combinations# 定义Apriori算法函数 def apriori(transactions, min_support, min_confidence):# 遍历数据&#xff0c;统计每个项的支持度 item_support {}for tr…

数学建模---包汤圆问题引发的思考

1.前言 &#xff08;1&#xff09;虽然我学习这个数学建模已经很长一段时间了&#xff0c;但是我认为自己始终是一个门外汉&#xff0c;只是学习了一下这个基本的建模软件使用方法&#xff0c;以及一些相关的知识&#xff0c;虽然参加了一次这个电工杯的比赛&#xff0c;但是这…

编译——链接

在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境&#xff1a; 第一种就是编译环境&#xff0c;在这个环境中源代码被转换成可执行的机器指令&#xff08;二进制指令&#xff09; 第二种是执行环境&#xff0c;它用于实现执行代码 翻译环境 其实翻译环境就是指编译和链…

数据结构和算法(2)---- Stack 的原理和实现

Stack 的定义和结构 栈(Stack)是仅限于在表尾进行插入和删除的线性表 我们把允许插入和删除的一端称为栈顶(top)&#xff0c;另一端称为栈底(bottom)&#xff0c;不含任何元素的栈称为空栈&#xff0c;栈也被称为先进后出(Last In First Out)的线性表&#xff0c;简称LIFO结构…

RabbitMQ消息队列 安装及基本介绍

一.MQ介绍 Message Queue &#xff08;MQ&#xff09;是一种跨进程的通信机制&#xff0c;用于在系统之间进行传递消息。MQ作为消息中间件&#xff0c;可以进行异步处理请求&#xff0c;从而减少请求响应时间和解耦 1.1 应用场景 1.1.1 系统之间通过MQ进行消息通信&#xff0…