首页 > 其他分享 >Cache相关知识整理

Cache相关知识整理

时间:2023-05-11 23:00:35浏览次数:40  
标签:缓存 struct 缓冲 Cache 知识 内存 整理 高速缓存

高速缓存的基本原理

参考资料:

在物理结构上,Cache由SRAM构成,SRAM比DRAM的速度快一一些,但是造价会更高。

高速缓存的结构能够用(S, E, B, m)这一个四元组来描述:

  • S : 该Cache有S个组
  • E : 每个组有E个缓存行
  • B : 每个缓存行存储B个字节的内存拷贝,这个实际上就是对内存的拷贝
  • m : 表示机器的地址位数,而S和B又将m地址分成3部分
    • 标记, t个位
    • 组索引, s个位
    • 快偏移, b个位

组索引,确定某个内存块存放于Cache的哪个组;标记用来确定这个内存块在这个组的哪个缓存行;块偏移则用来确定内存地址在这个缓存行的偏移地址。

这三个值唯一地标识了存储在高速缓存行中的块。

image-20230511203831491

给定一个内存地址,处理器按照如下步骤找到Cache中的某个内存块:

  1. 根据内存地址的组索引位定位到Cache的某个组
  2. 依次遍历这个组的缓存行,对比内存地址的标记位和缓存行中的标记位,只有当该缓存行的标记位和内存地址的标记位相同且设置了有效位的情况时,才表示处理器找到了这个缓存行
  3. 根据内存地址的快索引,找出该内存地址在该缓存行的字偏移

根据每个组中的行数E的不同,可以将Cache分成三种不同的类型

  • E = 1,即每组只包含一个行。称为直接映射高速缓存
  • E = 高速缓冲的所有行数。称为全相联高速缓存
  • E > 1 ,但不包括所有行数。称为组相联高速缓存

对于直接映射高速缓存,只需要通过组索引确定组号即可,不需要再次比对标记位。缺点是,对于映射到同一个组的内存行,只能存放在一个缓冲行,因此在某些情况下,会发生“抖动”(即反复地驱逐、加载相同的缓冲行),缓冲命中率极低

对于全相联高速缓存,每个内存行都能够存放于所有的缓冲行中,此时没有组索引,需要比对所有缓冲行的标记位。因此构造一个又大又快的全相联高速缓存是非常困难的,而且很昂贵。

对于组相联高速缓存,内存行被分配到某个组中,这个内存行可以占据这个组中的任意一个缓冲行。因此相比于直接映射高速缓存,能够有效抑制“抖动”现象;相比于全相联高速缓存,制作成本有所下降。

intel core i的高速缓存层次结构(图源CSAPP)如下:

image-20230511212535106

每个核有两个L1 cache,一个d-cache存放数据缓存,一个i-cache存放代码缓存, L3缓存则是所有核都共享。

其中L1缓存的大小为32KB,组数为64,相联度为8(即每个组有8个缓存行),块大小为64B。

常见的利用Cache进行优化的技巧

将那些经常一起获取的变量放得近一些

“近一些”是指,尽量放在同一个缓存行上。

下面是linux 2.4内核中的struct page结构,也能看到作者注释中写出了他对缓存行的考虑:

/*
 * Try to keep the most commonly accessed fields in single cache lines
 * here (16 bytes or greater).  This ordering should be particularly
 * beneficial on 32-bit processors.
 *
 */
typedef struct page {
	struct list_head list; 
    // 
	struct address_space *mapping;
	unsigned long index;    
    // 
	struct page *next_hash;
	atomic_t count;
	unsigned long flags;	
	struct list_head lru;
	unsigned long age;
	wait_queue_head_t wait;
	struct page **pprev_hash;
	struct buffer_head * buffers;
	void *virtual; /* non-NULL if kmapped */
	struct zone_struct *zone;
} mem_map_t;

其中的

struct address_space *mapping;
unsigned long index;  

这两个数据结构,mapping指向某个inode的address_space结构,它本身是一个基数树结构,而凭借index变量,可以快速定位基数树中的节点,因此这两个变量是经常被一起用的,这里将它们放入同一个缓存行,那么在使用mapping的同时,index变量也已经被加载到缓存行中了,节省了一次缓冲行加载操作,而且也减少了很多潜在的剔除、和重加载操作。

控制class\struct结构的大小

假设缓冲行的大小为64字节,那么尽量使得自定义class的大小要么能够整除64,要么是64的倍数。

这与处理器的默认内存对齐有着相同的缘由,因为处理器获取内存不是一个字节一个字节地存取的,高速缓存也不是一个字节一个字节地缓冲内存,它是以块为单位,比如以64字节为一块加载到缓冲行。

那么使得class的大小要么能够整除64,要么是64的倍数,能够保证对象跨缓冲行的行数最小。

比如对象的大小为32,一个缓冲行能够完整地存放两个对象:

image-20230511222014462

但如果一个对象的大小为48字节,一个缓冲行只能存放4/3个对象:

image-20230511222330889

那么如果我们要获取第二个对象,那么处理器需要加载两个缓冲行,也会增加很多潜在的剔除、和重加载操作,影响程序运行效率。

矩阵乘法

假设有m×r的矩阵A和r×n的矩阵B,对它们做乘法得到m×n的矩阵C

C代码如下:

void multiply_matrices(int A[m][r], int B[r][n], int C[m][n]) 
{ 
    int i, j, k; 
    for (i = 0; i < m; i++) { 
        for (j = 0; j < n; j++) { 
            for (k = 0; k < r; k++) {
                C[i][j] += A[i][k] * B[k][j]; 
        } 
    } 
} 

根据线性代数的知识,这是最简单的实现也符合我们直觉的实现方式。

程序对A、B两个矩阵的遍历模式如下,A是按行遍历,B是按列遍历:

image-20230511224337144

但是处理器是按行存放举矩阵的:

image-20230511224350623

那么这就导致上方的程序的最后一个循环内,每次存取B矩阵的一个元素,都可能引起一个CacheMiss,因为存取B的前后两个元素大概率不在同一个缓存行。

有什么方法优化吗?改变对B矩阵的存取模式即可,即也按行存取B矩阵即可。对程序的改动也比较简单,只要交换里面的两个的循环次序即可

void multiply_matrices(int A[m][r], int B[r][n], int C[m][n]) 
{ 
    int i, j, k; 
    for (i = 0; i < m; i++) { 
        for (k = 0; k < r; k++) { // 交换里面两个循环的次序
            for (j = 0; j < n; j++) { 
                C[i][j] += A[i][k] * B[k][j]; 
        } 
    } 
} 

标签:缓存,struct,缓冲,Cache,知识,内存,整理,高速缓存
From: https://www.cnblogs.com/HeyLUMouMou/p/17392502.html

相关文章

  • 8.电气件相关知识
    1.MSDMSD被称为手动维修保护开关,其内置高压保险丝,具有高压互锁功能,MSD的主要功能是为了保护在高压环境下从事电动汽车维修人员的安全。例如车辆外部高压线路出现短路情况时,MSD会立即断开内部保险丝,快速分离高压电路的连接。手动断开高压时,MSD高压互锁先断开,然后再断开高压回路,......
  • AWS RDS, ElastiCache
    WhichRDS(NOTAurora)featurewhenuseddoesnotrequireyoutochangetheSQLconnectionstring?   ReadReplicasaddnewendpointswiththeirownDNSname.Weneedtochangeourapplicationtoreferencethemindividuallytobalancethereadload.●Multi......
  • MongoDB整理
    MongoDB一、数据库(database)①什么是数据库?存储数据的仓库②为什么要有数据库?数据持久化③数据库能做什么?存储数据,可以通过网络访问④数据库的分类按照关系型分类:1、关系型数据库(MySQL、Oracle等)2、非关系型数据库(MongoDB、Redis)区别:关系型是创建表格,非关系型......
  • 最近VJ刷题整理
    BitsReverse题意:给出两个数,每次操作其中一个数,将其二进制位上连续的三个数翻转,求最小的操作次数Solution每次操作相当于交换了左右两个二进制位的数,所以一次操作只会改变奇数位/偶数位上的数,考虑到只用求最小的操作次数,我们可以将每个数的二进制位上的1所在的位置分奇偶存一下......
  • springcache + redis 配置支持缓存ttl失效
    packagetst;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.JsonTypeInfo;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.DeserializationFeature;importcom.......
  • Python的基础核心知识
    编程语言和编程编程语言语言:人与人之间沟通的媒介编程语言:人与计算机沟通的语言编程程序员通过计算机能够读懂的语言把自己的思想和逻辑写下来的过程编程的初衷是更好的奴隶计算机计算机五大组成部分部1.控制器2.运算器3.存储器4.输出设备5.输入设备计算机三大核心硬......
  • FastReport问题整理(转载)
    1.FastReport中如果访问报表中的对象?可以使用FindObject方法。TfrxMemoView(frxReport1.FindObject(’memo1′)).Text:=’FastReport’;2.FastReport中如何使用上下标?设置frxmemoview.AllowHTMLTags:=True;在Text输入如下上标:mm<sup>2</sup>下表:k<sub>6</sub>举一反三,你还可以......
  • drf知识点
    目录drf知识点1、web应用模式、API接口、接口测试工具postman、restful规范2、序列化与反序列化的概念、基于django原生编写5个接口、drf介绍和快速使用、cbv源码分析3、APIView执行流程(源码分析)、Request对象源码分析4、序列化器的序列化与反序列化5、断言、drf之请求与......
  • JWT相关知识点
    目录一、jwt介绍和原理概念构成与工作原理1.header2.payload3.signature本质原理jwt认证算法:签发与校验签发:根据登录请求提交来的账号+密码+设备信息签发token校验:根据客户端带token的请求反解出user对象drf项目的jwt认证开发流程(重点)补充base64编码解码drf-jwt安装和简......
  • 华为OD机试 知识图谱新词挖掘
    华为OD机试【4大宝典】再次上新题!①Python解华为机试题:https://dream.blog.csdn.net/article/details/129221789②C++解华为机试题:https://dream.blog.csdn.net/article/details/129472919③Java解华为机试题:https://dream.blog.csdn.net/article/details/129652513④......