首页 > 系统相关 >CSCI 2122任缓存和内存层次结构 解析

CSCI 2122任缓存和内存层次结构 解析

时间:2024-04-08 18:11:06浏览次数:27  
标签:缓存 CSCI cache 2122 内存 测试 模拟器 引用

CSCI 2122任务5
截止日期:2024年4月9日星期二晚上11:59,通过git提交
目标
本课业的目的是练习用C进行编码,并强化中讨论的概念类的指针、缓存和内存层次结构。在这项任务中,您将实现一个使用有限内存的缓存模拟器。
准备
1.完成工作分配0,或确保已安装完成工作分配所需的工具。
2.克隆您的课业存储库:
您的CSID在哪里。如果需要,请参阅课业0中的说明和Brightspace教程
你不知道怎么做。在存储库中有一个目录:cachex,用于编写代码。你应该设置一个此目录的CLion项目。目录内是一个测试目录,其中包含将每次提交代码时执行。请不要修改测试目录或根目录中的.gitlabci.yml文件。修改这些文件可能会破坏测试。这些文件将当课业被评分时,用原件代替。您将获得一个示例Makefile可用于构建程序的文件。如果您正在使用CLion,将从生成Makefile
CLion生成的CMakeLists.txt文件。
背景
快速内存非常昂贵。缓存设计器受其可使用的快速内存量的限制。此外快速存储器不仅必须存储被缓存的数据而且还必须存储所有元数据,
例如标签、有效位和时间戳。自然地,缓存设计者在硬件中实现之前先在软件中模拟他们的设计。在这项课业中,你也会这样做。您的任务是实现一个模拟缓存的缓存模块。缓存类型的选择取决于你您的缓存模块将提供两个参数:代 写CSCI 2122任缓存和内存层次结构 解析,您的缓存可以使用和M,模拟系统中的内存量,从中缓存数据。此外,您的模块将被提供一个指向大小为F的“快速”内存的指针。您的缓存模块可能只使用这个“快速”内存(除了局部变量)来实现缓存。简而言之,任何数据
需要管理缓存,以及缓存的数据必须存储在“快速”内存中。
缓存
回想一下,缓存是由几个参数定义的:
S: 集的数量
E: 每套的行数
B: 每行缓存的字节数缓存的大小为C=S x E x B。缓存的类型取决于以下参数:
•在直接映射缓存中,E=1,即每组有一(1)行,
•在全关联缓存中,S=1,即所有行都在一个集合中,以及
•在集合关联缓存中,S>1和E>1,即有多个集合,每个集合有多行。当缓存接收到内存引用时
1.将地址分解为标记、集合索引和偏移量。
2.使用索引来标识可以缓存引用内存的集合
3.使用标记来确定集合中的行是否正在缓存引用的内存
4.如果引用的存储器没有被高速缓存,
a.缓存确定集合是否包含未使用的行
b.如果没有未使用的行,缓存将收回已使用的行。
c.然后用包含参考的存储器块加载该行。
5.此时,所选集合中的一行正在缓存被引用的内存。缓存返回所引用的数据。使用何种类型的缓存完全取决于您。唯一的限制是高速缓存必须适合“快速”存储器的F字节,并且行大小B≥32字节。
参考流
引用流只是一系列内存引用(地址),表示程序运行并在运行时访问内存。第一个整数R表示后面的内存引用数。接下来的R个整数是内存地址。
缓存模拟器您的缓存模拟器将(i)系统配置作为输入,该系统配置包括:
•F_size:F_size≥256的“快速”内存的大小
•F_memory:指向“快速”内存的指针
•M_size:主存储器的大小
(ii)参考流,以及(iii)可选的“stats”命令,该命令使模拟器打印出
缓存命中/未命中计数和命中率。模拟器实例化被模拟的系统,然后通过将每个引用发送到缓存来处理引用流。缓存将转发请求到主存储器,如果请求导致未命中,则从存储器加载一行。一旦请求数据在缓存中,缓存返回请求的数据。模拟器计算命中和未命中的次数并且可以在参考流完成之后输出命中率。您的任务将是在缓存模拟器中实现缓存模块。任务:实现模拟器的cache.c您的任务是通过实现一个函数来实现cache.c模块。函数已声明
在cache.h中,并从main.c调用。函数为:int cache_get(无符号长地址,无符号长值)
此函数获取一个内存地址和一个指向值的指针,并加载一个位于并将其复制到值所指向的位置。也就是说,这就是CPU当它需要从内存加载一个单词时,它会从缓存中请求它。函数需要两(2)个参数:
•地址:要加载的值的位置。地址是内存引用来自参考流。
•值:指向单词要复制到的缓冲区的指针。函数在成功时返回1,在失败时返回0。该功能执行两个步骤:
1.检查缓存系统是否已初始化。如果没有,则初始化缓存。
2.通过返回指定内存地址的值来处理请求。
步骤1:检查和初始化缓存该函数可以访问在cache.h中定义的名为c_info的全局结构。该结构为
结构缓存信息{
void
F_memory;/指向“快速”内存的指针/
无符号int F_size;/“快速”内存的大小(字节)/
unsigned int M_size;/主内存大小(字节)/
};
指针c_info。F_memory指向大小为c_info的内存块。F_size。记忆是初始化为全部0。这是唯一的内存,除了在实现时可能使用的局部变量缓存。您不能使用calloc()或malloc(),也不能创建任何额外的静态或全局变量。建议的方法是定义一个结构,并将其放置在指向“快速”内存的开头到F_memory。结构可以指向表示集合或行的结构数组,这些集合或行也位于“快速”记忆。这些结构可包含指针,指向(存储数据的)行,并且保存在“快速”记忆中。在“快速”内存的开头的结构中有一个“initialized”标志,如果缓存为已初始化,否则为0。提示:在cache.c中创建一个从调用的静态init()函数
cache_get(),如果“initialized”标志为0。init()函数可以设置所有指针
结构。注意:由您决定缓存的集和行数。唯一的
限制是(1)行(B)的最小大小必须为32字节。以及(ii)一切都必须符合
F_size字节的内存。F_size将大于或等于256。提醒:其中一件事
init()应该做的是将initialized标志设置为1。
步骤2:处理请求
要处理请求,cache_get()函数应该:
1.将地址分解为标记、索引和偏移量。
2.使用索引查找正确的集合。
3.使用标记来确定包含地址的内存块是否在中的一行中
这套。
4.如果是(缓存命中),偏移量用于定位该行中的单词,则应复制该单词
进入值所指向的缓冲区,然后函数返回。
5.否则,这是缓存未命中。在这种情况下,将选择一个受害者行,并使用的标记进行初始化
所需的内存块,并通过调用函数加载
int memget(无符号int地址,void*缓冲区,无符号int大小)
它在cache.h中声明,在main.c中定义。此函数将地址作为
第一个参数,指向应该加载块的缓冲区的指针,以及的大小要得到的块。提示,缓冲区应该指向行中存储块的部分。这个函数在成功时返回1,在失败时返回0。对memget()的每次调用都算作未命中。缓存模拟器的其余部分已经为您实现了!J
高速缓存主线cachex的main.c已经为您实现。以下是对其功能的简要描述。输入
cachex从stdin读取输入。输入包括三个部分:(i)系统配置;(ii)a参考流;以及(iii)可选的“stats”命令。系统配置由两个整数组成:
•F:“快速”内存大小
•M:内存大小引用流由表示引用数量的整数N和后面的N个引用组成。每个引用都是一个介于0和M–8之间的整数,表示被引用的内存中的地址。在N个内存引用之后,可能会出现可选的“stats”命令。此命令包括一个单词“stats”,并使模拟器打印出命中率、未命中率和命中率。
处理
当cachex开始运行时,它读取系统配置,分配系统中的内存并初始化c_info结构。主存储器被初始化为一系列伪随机数(这些数字看起来是随机的,但实际上不是)。然后,它进入主循环并处理参考流:
•对于每个引用,都会调用cache_get()。
•将加载值与预期值进行比较
Example
Input Output
1024 65536
Loaded value [0xb9cb17b29e5109d2] @ address 0x00000016
Loaded value [0x0394fee63984c8dc] @ address 0x00000030
Loaded value [0x8eba29a6bb1465ff] @ address 0x00000046
Loaded value [0x3ce65cc676176add] @ address 0x00001016
Loaded value [0xb9cb17b29e5109d2] @ address 0x00000016
Loaded value [0x3ce65cc676176add] @ address 0x00001016
Loaded value [0x425a273223d06058] @ address 0x00000816
Loaded value [0x3ce65cc676176add] @ address 0x00001016
Loaded value [0xb9cb17b29e5109d2] @ address 0x00000016
Cache hits: 4, misses: 5
提示和建议
•您将需要两个structs,一个用于缓存,另一个用于行。您可能还需要一个作为套装。
•从根本上讲,缓存是集合的数组,集合是行的数组。
•您只需要修改一个文件:cache.c。
•没有太多代码可写(我的解决方案不到100行)。
分级
如果你的程序没有编译,它将被视为不起作用且质量极差,这意味着你将收到0的解决方案。
课业将根据三个标准进行评分:
功能:“它是否按照规范工作?”。这是通过以下自动方式确定的
在多个输入上运行程序,并确保输出与预期输出匹配。这个
分数是根据你的程序通过的测试次数来确定的。所以,如果你的程序通过了
t/t测试,您将获得该比例的分数。
表演:“它演得好吗?”。这是通过运行您的
在几个输入上编程,并将缓存的基准与解决方案的基准进行比较。
解决方案质量:“这是一个好的解决方案吗?”这考虑了您的方法和算法
解决方案是正确的。这是通过目视检查代码来确定的。有可能取得好成绩
在这方面,即使您有导致代码无法通过某些测试的错误。
代码清晰度:“它写得好吗?”这考虑了解决方案是否正确格式化、文档记录良好以及是否遵循编码风格准则。为了清晰起见,将指定一个整体标记。请参阅
Brightspace课程课业部分的风格指南。
课业提交
提交和测试是使用Git、Gitlab和Gitlab CI/CD完成的。您可以多次提交
愿望,直到最后期限。每次提交时,都会执行功能测试,您可以查看
测试结果。若要提交,请使用与分配0相同的过程。
未提交课业测试
通过提交进行测试可能需要一些时间,尤其是在加载了服务器的情况下。您可以在没有
使用提供的runtests.sh脚本提交代码。运行不带参数的脚本
将运行所有测试。运行测试编号为00、01、02、03…09的脚本将运行特定的
测验请参阅下面的脚本运行方式。
准备好程序运行
如果您直接在unix服务器上进行开发,
1.通过SSH连接到远程服务器,并确保您在cachex目录中。
2.确保程序是通过运行make编译的。
如果您正在使用CLion
1.如CLion教程中所述,在远程服务器上运行程序。
2.通过工具打开远程主机终端→ 打开远程主机终端
如果您正在使用VSCode
1.如VSCode教程中所述,在远程服务器上运行程序。
2.单击窗口下半部分的“终端”窗格或通过“终端”→ 新建终端运行测试脚本
3.使用以下命令在终端中运行脚本:
./runtest.sh
运行所有测试,或指定运行特定测试的测试编号,例如:
./runtest.sh 07
运行基准测试脚本
3.使用以下命令在终端中运行脚本:
./runbench.sh
运行所有测试,或指定运行特定测试的测试编号,例如:
./runbench.sh 03
您将在终端窗口中看到台架运行。

标签:缓存,CSCI,cache,2122,内存,测试,模拟器,引用
From: https://www.cnblogs.com/gzashang/p/18121982

相关文章

  • ThinkPHP 实现简单的缓存锁
    使用ThinkPHP实现简单的缓存锁在开发过程中,为了避免重复提交等问题,我们常常需要使用缓存锁来控制并发访问。本文将介绍如何利用ThinkPHP框架实现一个简单的缓存锁功能。锁Key的生成在实现缓存锁之前,首先需要确定锁的唯一标识,这里我们采用了学生ID和费用数据ID......
  • Chrome浏览器前端开发调试时强制更新js、css静态资源文件缓存的方法
    以Chrome浏览器为例,国产浏览器未做全面测试。前端开发静态文件时,浏览器访问会缓存样式、图片、js等,怎么快速更新缓存。以下方法特别适合只想清除某个网页的缓存,而不想清除全部浏览器缓存可以采用以下方法。一、强制刷新同时按住ctrl+f5或ctrl+shift+r进行访问页面强制刷新,一般......
  • Chromium 自定义缓存策略
    目录CefRequestHandler在什么位置实现我如何将本地资源作为该请求资源返回呢?我怎么缓存网络资源呢,比如图片和视频?CefResourceHandler如何实现缓存图片和视频,缓存时间无限长,设置缓存路径?demoMyResourceHandler在哪里设置?ChromiumEmbeddedFramework(CEF)是一个开源库,用于......
  • 【知识点】Redis-缓存-缓存击穿
    缓存击穿:缓存中一个热点数据过期或失效时,由于该数据非常受欢迎,会有大量请求直接打到数据库上,导致数据库负载增大、相应变慢甚至瘫痪。解决方式:互斥锁在查询数据库之前首先获取分布式锁,更新redis之后再释放锁,可以保证数据的强一致性。优缺点:优点:强一致性缺点:性能差逻辑......
  • HTTP的强制缓存和协商缓存
    HTTP的强制缓存和协商缓存HTTP的缓存技术强制缓存ExpiresCache-Control协商缓存If-Modified-Since和Last-ModifiedIf-None-Match和ETag优先级可被缓存的请求方法总结HTTP的缓存技术  当我们进行HTTP请求时,需要将请求报文发送给对端,当服务端收到请求后会做出合适......
  • Spring Boot数据缓存之Spring缓存抽象 @Cacheable初体验
    在数据缓存之Cache规范JSR107中对Spring的缓存抽象有了一定的了解,下面通过示例实战对其深入探讨。需要注意的是使用Spring缓存抽象时要关注两点:①确定那些方法需要被缓存    ②缓存策略具体案例如下:1、导入依赖Mysql、Mybatis、W......
  • 【知识点】Redis-缓存-缓存穿透
    缓存穿透:查询一个不存在的数据,Mysql查询不到也没有写入缓存,导致每次请求都会查询数据库。(比如恶意请求)解决方案:缓存空数据:返回数据为空时仍然缓存(但是需要加过期时间)。优点:简单缺点:消耗内存,可能存在数据不一致情况。布隆过滤器布隆过滤器使用Bitmap(位图)来记载一个数据是......
  • Redis缓存三兄弟
    Redis缓存的问题都是因为缓存过期,导致大量请求打到数据库,给数据库添加了压力。以下是典型的三个缓存问题。缓存穿透概念缓存穿透:频繁请求缓存和数据库中没有的数据,导致数据库的压力过大解决方案规则校验:增加对key的规则校验,防止恶意请求设默认值:数据库中没有数据时,给该......
  • Redis缓存穿透和缓存雪崩
    一、缓存穿透1什么是缓存穿透        缓存穿透说简单点就是大量请求的key根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的key发起大量请求,导致大量请求落到数据库。2处理流程如下图所示,用户......
  • LRU缓存(超详细注释)
    /***表示双向链表中的节点。*/classNode{constructor(key=0,value=0){this.key=key;//缓存条目的唯一标识符。this.value=value;//与键关联的值。this.prev=null;//引用列表中的上一个节点。this.next......