您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

CPU Cache是如何映射与寻址的?

时间:2023-08-29 13:16:46  来源:微信公众号  作者: 小牛呼噜噜
  • CPU Cache的组织结构

  • Cache与内存地址映射

    • 直接映射

    • 全相联映射

    • 组相联映射

  • Cache寻址方式

  • VIVT、VIPT、PIPT(补充)

  • 尾语

  • 往期推荐

 

哈喽,大家好,我是呼噜噜,在上一篇文章我们介绍了突破计算机性能瓶颈的利器CPU Cache,今天我们来聊聊CPU Cache的组织结构及其它是如何映射与寻址的?

CPU Cache的组织结构

CPU Cache的组织结构:CPU Cache被划分成多个组Set,每个Set中还可以有多个行Cache Line需要注意的是Cache Line是CPU Cache中的基本缓存单位,也有人叫它(Block),也就是说它每次读写不是一个字节的去读写,而是以Cache Line为单位,一块块地去读取

一般主流的 CPU 的 Cache Line 大小是64 Byte,当然也有其他大小,在Cache块比较小的时候,这时的命中率很低,随着块大小的增加,空间局部性起作用,命中率会快速提高;如下图:
图片

这种增加趋势在某一个最佳块大小处达到最大值。当到达顶峰以后,命中率随着块大小的增加反而会逐渐降低。因为当块大小非常大时,进入Cache中的许多数据可能根本用不上,同时随着块继续增大,时间局部性会逐渐失去作用

 

而 CPU Line 又由有效标志Valid标志Tag数据块Data这3个部分组成,其中data是真正要来缓存一片连续内存地址中的数据,而tag是用来查找Cache Line的标志,存储这片连续数据的公共地址,valid表示当前缓存的数据是否有效,也可以用来协助查找Cache Line

可以参考下图:

图片

Cache与内存地址映射

我们知道高速缓存的速度要远远快于主存(内存)的速度,但Cache的容量却是远远小于主存,相较于主存的价格,缓存则昂贵的多

另一方面CPU Cache是需要缓存内存中的数据,无论对Cache数据读取还是写入,CPU都需要知道访问的内存数据,对应于Cache上的哪个位置,而由于Cache容量不够,无法做到Cache与内存地址一一对应

那么Cache是如何与内存地址进行映射的?

其实CPU Cache主要有3种的实现方式:

  1. 直接映射(direct-mApped),也就是每个组Set只有一个Cache Line,选中Set之后不需要和Set中的每个Line进行比对
  2. 全相连映射(fully associative),即只有一个Set,所以这个Set中包含所有的Line
  3. 组相连映射(set-associative ), 有多个Set,每个Set有多个Line;需要注意的是,组相连也会被称为路Way,比如6路组相联,表示每个Set有6个Line

直接映射

直接映射会在内存块和缓存块之间建立起固定的映射关系,也就是内存中的某个块总是映射到Cache的一特定块上

linux内核中,并非总使用基于我们更熟悉的页来当页缓存。内核的早期版本使用了块缓存,来加速文件系统,提高系统性能

我们这里以8块主存和4块(行)为例,具体如下图所示:

图片

通过上图,我们可以发现B0块和B4块主存只能映射到Cache的第0块,B3块和B7块只能只能映射到Cache的第3块,其他内存块同理

其实相当于给主存空间按照Cache Line的大小(也就是Line的行数)来进行分区,每个内存块编号需要与Cache Line的大小取模,得到固定的映射位置即区内编号,映射到与它区内编号相同的Cache Line

 

可以发现直接映射的优点:查找效率高,硬件设备简单,地址变换速度快,但是它也有缺点:由于每个主存块只有一个固定位置可存放,即使Cache中别的Line空着也不能占用,无法充分利用Cache空间,这样冲突概率较大

如果冲突了,这多个内存块会不断地交替装入固定的映射Cache Line中,导致缓存命中率降低,所以直接映射适合大容量Cache

全相联映射

图片

全相联映射 主存的数据可以放在任意一个Cache line中,映射方式比较灵活,Cache的利用率高,块冲突的概率低,因为只有当所有的Line都被占满后才会出现冲突

但是另一方面,访问缓存时,每次都要和全部Line中的内存进行比较,速度低延迟高是它无法避免的缺点,因此适合于小容量Cache采用

组相联映射

图片组相联

映射是直接映射和全相联映射的折中方案,吸取2者的优点,尽量避免2者的缺点,组间采用直接映射,组内采用全相联映射,即主存块存放到哪个组Set是固定的,存到Set内哪一个Cache Line是灵活随意的

当查找缓存时,不再需要全部进行遍历,只需先查到cache的组号,然后在那一组内,进行小范围遍历。这样冲突概率较小,同时命中率较高,所以这种方式在现代的处理器中得到了广泛的应用

Cache寻址方式

通过前文的阅读,相信大家都对CPU Cache的组织结构和Cache与内存地址映射方式有所了解,而Intel多数处理器的 L1 Cache 都是32KB,8-Way 组相联,Cache Line 是 64 Byte,我们以这个参数为例,来看看Cache是如何寻址的?

因为Cache Line是最小单位(64Bytes),所以可以得出Cache Line的条数 = 32KB /64=512,每一Way的Cache Line条数 = 512 / 8 = 64(也就是每一个Set的Cache Line条数)

那么我们可以得到,每一Set的内存大小 = 64 x 64 = 4096B=4KB,是不是很熟悉,这不正是一个内存页page的大小嘛!本文前面用块来划分内存,和页一样都是内存划分的方式,在操作系统中,页是固定大小的存储单元,而块是可变大小的存储单元

首先我们得知道内存地址如何被分解?内存地址被分成了3部分:tag, set index和block offset

  1. tag:与Cache Line中的tag匹配,内存地址的前24bit
  2. set index:set索引,用来寻找定位Set,内存地址中间的6个bit,正好能查询2^6=64个line
  3. block offset:块偏移量,用来寻找Cache Line里data中的内存数据,内存地址最后6位

 

那么Cache寻址的具体方式,我们可以将其分为3个步骤:

  1. 先根据set index来找到对应的Set
  2. 接着根据tag在上一步步找到的set中找到对应的Cache Line,如果找到且对应的有效位valid为1,表示缓存命中,反之无论其中的tag和Cache Line 里的数据内容是什么,CPU 都不会管这些数据,而是会直接访问主存,重新加载数据(当然这里涉及到缓存一致性的问题,比较复杂,先挖个坑,本文暂不讲解),那如果没找到,说明当前发生cache缺失,即cache miss
  3. 最后根据block offset在上一步找到的Cache Line的data中找到对应内存的数据

笔者这里再吐血画了张图,帮助大家更加直观了解Cache寻址的具体方式

图片

VIVT、VIPT、PIPT(补充)

最后再介绍一下几个概念,就是Cache寻址时,可以根据物理地址,也可以根据虚拟地址,或者二者结合起来查找

  1. VIVT(Virtually Indexed, Virtually Tagged )表示index和tag都是采用虚拟地址
  2. VIPT(Virtually Indexed, Physically Tagged )表示index采用虚拟地址,tag采用物理地址,一般用于L1 Cache
  3. PIPT(Physically Indexed, Physically Tagged )表示index采用物理地址,tag采用物理地址,一般用于L2 Cache

尾语

本文先后介绍了CPU Cache的组织结构,Cache与内存地址映射的3种方式,以组相联Cache来讲解Cache的寻址方式,画图太耗心神了,先到这了,后面我们继续更新Cache的缓存一致性,提高代码性能等难点

参考资料:

《Cache: a place for concealment and safekeeping》

https://blog.csdn.NET/qq_38768922/article/detAIls/78737284

http://staff.ustc.edu.cn/~hdrq/jsjzcyl/text/chapter5/sec3/part4/r1.htm



Tags:CPU Cache   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
CPU Cache是如何映射与寻址的?
CPU Cache的组织结构 Cache与内存地址映射 直接映射 全相联映射 组相联映射 Cache寻址方式 VIVT、VIPT、PIPT(补充) 尾语 往期推荐 哈喽,大家好,我是呼噜噜...【详细内容】
2023-08-29  Search: CPU Cache  点击:(180)  评论:(0)  加入收藏
突破计算机性能瓶颈的利器CPU Cache
本文简单介绍了计算机性能瓶颈产生的原因,缓存及其发展历史,最后讲解了缓存弥补CPU和内存性能差异的原理,后面我们会继续更详细深入地介绍Cache的组织结构、缓存一致性,以及如何...【详细内容】
2023-08-02  Search: CPU Cache  点击:(242)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条