27 Cache学习

文章介绍了Cache的基本概念,强调其在提升处理器取数据速度中的作用。直接映射缓存将Cache分为固定大小的块,每个块包含数据和标签信息。两路组相连缓存则将Cache分为两部分,提供更大的地址映射灵活性,从而优化数据访问效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cache 学习

Cache指的是高速缓存简称缓存,原始意义是指访问速度比一般随机存取存储器(RAM)快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。
Cache的容量大小一般只有1KB到32KB,而这相较于内存存储的几个GB甚至TB的数据来说,Cache的容量是微乎其微的,Cache只能缓存内存的一小部分数据,但是Cache依然能够让处理器取到大部分需要的数据,其中的原理是内存中“程序执行与数据访问的局域性行为
请添加图片描述

直接映射缓存

cache的大小被称为 cache size,表示cache可以缓存的最大数据的大小,我们将cache平均分为很多块,每一块被称为cache line,其大小为cache line size。
现在的硬件设计中,一般cache line的大小是4-128 Bytes。请添加图片描述
cache与主存之间的对应,在硬件中完成,从而确保了较小的cache能够映射到更大的主存中。
请添加图片描述
上面是一个例子,8行cachelin,每个大小为 8个字节,上述图片中,index利用三位来映射cache编号,offset利用三位来映射字节编号,引入tag array区域,tag array和data array一一对应。每一个cache line都对应唯一一个tag,tag中保存的是整个地址位宽去除index和offset使用的bit剩余部分。
为什么不用1byte作为cacheline,因为每个cacheline中都放有tag的信息,如果每个都有tag的信息那么会浪费很大的内存。

在这里插入图片描述
上述是一个直接缓存相连的例子,此时,若读取0x00的信息,cache缺失,cpu从主存中读取数据,随后读取0x40的信息,cache仍然确缺失,cpu从主存中读取数据,随后读取0x80的信息,仍然缺失,本质上和读取主存没有任何区别,并且浪费了更多的时间在控制的过程中。

两路组相连缓存(Two-way set associative cache)

我们依然假设64 Bytes cache size,cache line size是8 Bytes。什么是路(way)的概念。我们将cache平均分成多份,每一份就是一路。因此,两路组相连缓存就是将cache平均分成2份,每份32 Bytes。如下图所示。请添加图片描述

### 寄存器缓存编程实现 寄存器缓存编程通常涉及硬件级别的控制和访问,例如通过ARM架构中的`CLIDR_EL1`寄存器获取缓存层次结构的信息。以下是基于提供的引用以及相关知识的一个具体实现示例。 #### 获取缓存层次结构信息 在ARM架构中,可以通过读取`CLIDR_EL1`寄存器来获得关于系统中缓存层次结构的关键信息。这包括每级缓存的类型(数据缓存、指令缓存或统一缓存)、一致性特性和其他属性[^1]。 下面是一个简单的汇编代码片段,用于从ARM CPU中读取`CLIDR_EL1`寄存器的内容: ```asm // ARM Assembly Code to read CLIDR_EL1 register mrs x0, clidr_el1 // Read the value of CLIDR_EL1 into register x0 ret // Return from function ``` 这段代码使用了ARM的`MRS`指令将`CLIDR_EL1`寄存器的值加载到通用寄存器`x0`中。此操作允许程序员进一步解析该寄存器的数据位以提取有关缓存层次结构的具体细节。 #### 解析CLIDR_EL1寄存器 一旦获得了`CLIDR_EL1`寄存器的原始值,就需要对其进行解析以便于理解和应用。以下Python脚本展示了如何解析这些数据: ```python def parse_clidr(clidr_value): levels = [] for i in range(7): # There are up to 7 cache levels defined by bits [27:3] type_bits = (clidr_value >> (i * 3)) & 0b111 if type_bits != 0: types = { 0b000: 'No Cache', 0b001: 'Instruction Cache only', 0b010: 'Data Cache only', 0b011: 'Unified Cache' } levels.append(f'Level {i}: {types.get(type_bits, "Unknown")}') return levels # Example usage with a hypothetical CLIDR_EL1 value clidr_example = 0x76543210 parsed_levels = parse_clidr(clidr_example) for level_info in parsed_levels: print(level_info) ``` 上述函数接受一个整数值作为输入参数,并返回描述各个缓存层类型的列表。它利用位移运算符`(>>)`逐个检查每个缓存层级对应的三位字段,从而判断其类别。 #### 并发环境下的序列管理 当涉及到线程或核环境中处理共享资源时,则可能需要用到类似于引用提到过的`Sequence`类及其内部使用的Padding技术来减少伪共享的影响[^3]。虽然这不是直接针对寄存器的操作,但在现代高性能计算场景下却是不可或缺的一部分。 对于CUDA编程而言,可以参考Bruce Fan在其GitHub项目中分享的一些样例代码[^2],学习如何有效地管理和优化GPU上的内存布局与访问模式,这对于提升整体性能至关重要。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值