如何利用CPU Cache写出高性能代码,看这些图就够了!

世界就像个巨大的马戏团,它让你兴奋,却让我惶恐,因为我知道散场永远是——有限温存,无限辛酸。

——卓别林


我们平时编写的代码最后都会交给CPU来执行,如何能巧妙利用CPU写出性能比较高的代码呢?看完这篇文章您可能会有所收获。

先提出几个问题,之后我们逐个击破:

初入宝地:什么是CPU Cache?

连类比事:为什么要有Cache?为什么要有多级Cache?

挑灯细览:Cache的大小和速度如何?

追本溯源:什么是Cache Line?

旁枝末叶:什么是Cache一致性?

触类旁通:Cache与主存的映射关系如何?

更上一层:如何巧妙利用CPU Cache编程?

1. 什么是CPU Cache?

如图所示:

CPU Cache可以理解为CPU内部的高速缓存,当CPU从内存中读取数据时,并不是只读自己想要的那一部分,而是读取更多的字节到CPU高速缓存中。当CPU继续访问相邻的数据时,就不必每次都从内存中读取,可以直接从高速缓存行读取数据,而访问高速缓存比访问内存速度要快的多,所以速度会得到极大提升。

2. 为什么要有Cache?为什么要有多级Cache?

为什么要有Cache这个问题想必大家心里都已经有了答案了吧,CPU直接访问距离较远,容量较大,性能较差的主存速度很慢,所以在CPU和内存之间插入了Cache,CPU访问Cache的速度远高于访问主存的速度。

CPU Cache是位于CPU和内存之间的临时存储器,它的容量比内存小很多但速度极快,可以将内存中的一小部分加载到Cache中,当CPU需要访问这一小部分数据时可以直接从Cache中读取,加快了访问速度。

想必大家都听说过程序局部性原理,这也是CPU引入Cache的理论基础,程序局部性分为时间局部性和空间局部性。时间局部性是指被CPU访问的数据,短期内还要被继续访问,比如循环、递归、方法的反复调用等。空间局部性是指被CPU访问的数据相邻的数据,CPU短期内还要被继续访问,比如顺序执行的代码、连续创建的两个对象、数组等。因为如果将刚刚访问的数据和相邻的数据都缓存到Cache时,那下次CPU访问时,可以直接从Cache中读取,提高CPU访问数据的速度。

一个存储器层次大体结构如图所示,速度越快的存储设备自然价格也就越高,随着数据访问量的增大,单纯的增加一级缓存的成本太高,性价比太低,所以才有了二级缓存和三级缓存,他们的容量越来越大,速度越来越慢(但还是比内存的速度快),成本越来越低。

3. Cache的大小和速度如何?

通常越接近CPU的缓存级别越低,容量越小,速度越快。不同的处理器Cache大小不同,通常现在的处理器的L1 Cache大小都是64KB。

那CPU访问各个Cache的速度如何呢?

如图所示,级别越低的高速缓存,CPU访问的速度越快。

CPU多级缓存架构大体如下:

L1 Cache是最离CPU最近的,它容量最小,速度最快,每个CPU都有L1 Cache,见上图,其实每个CPU都有两个L1 Cache,一个是L1D Cache,用于存取数据,另一个是L1I Cache,用于存取指令。

L2 Cache容量较L1大,速度较L1较慢,每个CPU也都有一个L2 Cache。L2 Cache制造成本比L1 Cache更低,它的作用就是存储那些CPU需要用到的且L1 Cache miss的数据。

L3 Cache容量较L2大,速度较L2慢,L3 Cache不同于L1 Cache和L2 Cache,它是所有CPU共享的,可以把它理解为速度更快,容量更小的内存。

当CPU需要数据时,整体流程如下:

会最先去CPU的L1 Cache中寻找相关的数据,找到了就返回,找不到就去L2 Cache,再找不到就去L3 Cache,再找不到就从内存中读取数据,寻找的距离越长,自然速度也就越慢。

4. Cache Line?

Cache Line可以理解为CPU Cache中的最小缓存单位。Main Memory-Cache或Cache-Cache之间的数据传输不是以字节为最小单位,而是以Cache Line为最小单位,称为缓存行。

目前主流的Cache Line大小都是64字节,假设有一个64K字节的Cache,那这个Cache所能存放的Cache Line的个数就是1K个。

5. 写入策略

Cache的写入策略有两种,分别是WriteThrough(直写模式)WriteBack(回写模式)

直写模式:在数据更新时,将数据同时写入内存和Cache,该策略操作简单,但是因为每次都要写入内存,速度较慢。

回写模式:在数据更新时,只将数据写入到Cache中,只有在数据被替换出Cache时,被修改的数据才会被写入到内存中,该策略因为不需要写入到内存中,所以速度较快。但数据仅写在了Cache中,Cache数据和内存数据不一致,此时如果有其它CPU访问数据,就会读到脏数据,出现bug,所以这里需要用到Cache的一致性协议来保证CPU读到的是最新的数据。

6. 什么是Cache一致性呢?

多个CPU对某块内存同时读写,就会引起冲突的问题,被称为Cache一致性问题。

有这样一种情况:

  a.   CPU1读取了一个字节offset,该字节和相邻的数据就都会被写入到CPU1的Cache.

  b.   此时CPU2也读取相同的字节offset,这样CPU1和CPU2的Cache就都拥有同样的数据。

  c.   CPU1修改了offset这个字节,被修改后,这个字节被写入到CPU1的Cache中,但是没有被同步到内存中。

  d.   CPU2 需要访问offset这个字节数据,但是由于最新的数据并没有被同步到内存中,所以CPU2 访问的数据不是最新的数据。

这种问题就被称为Cache一致性问题,为了解决这个问题大佬们设计了MESI协议,当一个CPU1修改了Cache中的某字节数据时,那么其它的所有CPU都会收到通知,它们的相应Cache就会被置为无效状态,当其他的CPU需要访问此字节的数据时,发现自己的Cache相关数据已失效,这时CPU1会立刻把数据写到内存中,其它的CPU就会立刻从内存中读取该数据。

MESI协议是通过四种状态的控制来解决Cache一致性的问题:

M:代表已修改(Modified) 缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必须回写到主存,状态变为共享(S).

E:代表独占(Exclusive) 缓存行只在当前缓存中,但是干净的(clean)--缓存数据同于主存数据。当别的缓存读取它时,状态变为共享(S);当前写数据时,变为已修改(M)状态。

S:代表共享(Shared) 缓存行也存在于其它缓存中且是干净(clean)的。缓存行可以在任意时刻抛弃。

I:代表已失效(Invalidated) 缓存行是脏的(dirty),无效的。

四种状态的相容关系如下:

这里我们只需要知道它是通过这四种状态的切换解决的Cache一致性问题就好,具体状态机的控制实现太繁琐,就不多介绍了,这是状态机转换图,是不是有点懵。

7. Cache与主存的映射关系?

直接映射

直接映射如图所示,每个主存块只能映射Cache的一个特定块。直接映射是最简单的地址映射方式,它的硬件简单,成本低,地址转换速度快,但是这种方式不太灵活,Cache的存储空间得不到充分利用,每个主存块在Cache中只有一个固定位置可存放,容易产生冲突,使Cache效率下降,因此只适合大容量Cache采用。


例如,如果一个程序需要重复引用主存中第0块与第16块,最好将主存第0块与第16块同时复制到Cache中,但由于它们都只能复制到Cache的第0块中去,即使Cache中别的存储空间空着也不能占用,因此这两个块会不断地交替装入Cache中,导致命中率降低。

直接映射方式下主存地址格式如图,主存地址为s+w位,Cache空间有2的r次方行,每行大小有2的w次方字节,则Cache地址有w+r位。通过Line确定该内存块应该在Cache中的位置,确定位置后比较标记是否相同,如果相同则表示Cache命中,从Cache中读取。

全相连映射

全相连映射如图所示,主存中任何一块都可以映射到Cache中的任何一块位置上。

全相联映射方式比较灵活,主存的各块可以映射到Cache的任一块中,Cache的利用率高,块冲突概率低,只要淘汰Cache中的某一块,即可调入主存的任一块。但是,由于Cache比较电路的设计和实现比较困难,这种方式只适合于小容量Cache采用。

全相连映射的主存结构就很简单啦,将CPU发出的内存地址的块号部分与Cache所有行的标记进行比较,如果有相同的,则Cache命中,从Cache中读取,如果找不到,则没有命中,从主存中读取。

组相连映射

组相联映射实际上是直接映射和全相联映射的折中方案,其组织结构如图3-16所示。主存和Cache都分组,主存中一个组内的块数与Cache中的分组数相同,组间采用直接映射,组内采用全相联映射。也就是说,将Cache分成u组,每组v块,主存块存放到哪个组是固定的,至于存到该组哪一块则是灵活的。例如,主存分为256组,每组8块,Cache分为8组,每组2块。

主存中的各块与Cache的组号之间有固定的映射关系,但可自由映射到对应Cache组中的任何一块。例如,主存中的第0块、第8块……均映射于Cache的第0组,但可映射到Cache第0组中的第0块或第1块;主存的第1块、第9块……均映射于Cache的第1组,但可映射到Cache第1组中的第2块或第3块。

     

常采用的组相联结构Cache,每组内有2、4、8、16块,称为2路、4路、8路、16路组相联Cache。组相联结构Cache是前两种方法的折中方案,适度兼顾二者的优点,尽量避免二者的缺点,因而得到普遍采用。

组相连映射方式下的主存地址格式如图,先确定主存应该在Cache中的哪一个组,之后组内是全相联映射,依次比较组内的标记,如果有标记相同的Cache,则命中,否则不命中。

在网上找到了三种映射方式下的主存格式对比图,大家也可以看下:

8. Cache的替换策略?

Cache的替换策略想必大家都知道,就是LRU策略,即最近最少使用算法,选择未使用时间最长的Cache替换。

9. 如何巧妙利用CPU Cache编程?

const int row = 1024;
const int col = 1024;
int matrix[row][col];//按行遍历
int sum_row = 0;
for (int r = 0; r < row; r++) {for (int c = 0; c < col; c++) {sum_row += matrix[r][c];}
}//按列遍历
int sum_col = 0;
for (int c = 0; c < col; c++) {for (int r = 0; r < row; r++) {sum_col += matrix[r][c];}
}

上面是两段二维数组的遍历方式,一种按行遍历,另一种是按列遍历,乍一看您可能认为计算量没有任何区别,但其实按行遍历比按列遍历速度快的多,这就是CPU Cache起到了作用,根据程序局部性原理,访问主存时会把相邻的部分数据也加载到Cache中,下次访问相邻数据时Cache的命中率极高,速度自然也会提升不少。

平时编程过程中也可以多利用好程序的时间局部性和空间局部性原理,就可以提高CPU Cache的命中率,提高程序运行的效率。

5T技术资源大放送!包括但不限于:C/C++,Arm, Linux,Android,人工智能,单片机,树莓派,等等。在公众号内回复「peter」,即可免费获取!!

 记得点击分享在看,给我充点儿电吧

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对视频剪辑应用灰度图像变换+Moviepy生成灰度视频处理遇到几个有意思的问题

一、引言 最近在学习图像处理的《直方图处理》&#xff0c;对直方图均衡处理效果感觉非常有用。 以前学习Moviepy音视频剪辑时&#xff0c;用的卓别林的一个黑白视频片段&#xff0c;感觉视频的噪点比较多&#xff0c;画面也整体偏暗&#xff0c;不禁想看看如果对其进行直方图…

大厂正在「去大厂化」

大厂逐渐不再是「大厂」。 撰文 | 佘宗明 大厂还值得去吗&#xff1f; 这成了摆在很多年轻人面前的问题。 搁几年前&#xff0c;这都不能称之为问题。 扁平化管理、快速上升空间、弹性工作制……比JK制服还诱惑。「财务自由」的召唤&#xff0c;更是胜却人间无数情怀。 那现在呢…

无心剑中译伊玛·拉扎罗斯《新巨人·自由女神》

文章目录 无心剑中译伊玛拉扎罗斯《新巨人自由女神》译友们中译伊玛拉扎罗斯《新巨人自由女神》1. 岩子版2. MNES版3. 天河版4. 铁冰版5. 好好做虾版6. 愚冠版卓别林十大经典语录卓别林最伟大的演讲《为自由而战斗》无心剑中译迈克尔杰克逊《自由无拘束》《被讨厌的勇气》- 什么…

当我真正开始爱自己——查理·卓别林

As I began to love myself I found that anguish and emotional sufferingare only warning signs that I was living against my own truth.Today, I know, this is “AUTHENTICITY”. As I began to love myself I understood how much it can offend somebodyAs I try to f…

快速做出原型

给定五六个维度约束下对比两个软件的表现&#xff0c;要用数据说话。这五六个维度&#xff0c;不限于丢包率&#xff0c;固有延时&#xff0c;抖动等。 若两个维度&#xff0c;一张表格即可展现&#xff0c;若四个维度&#xff0c;一个四维立方体可以展示&#xff0c;二维单元…

moviepy第一天|模糊视频中卓别林的头,并添加一个文本生成的结尾clip,同时保留音频

MoviePy(完整文档)是一个用于视频编辑的Python库:剪切,串联,标题插入,视频合成(又名非线性编辑),视频处理和创建自定义效果。有关一些使用示例,请参阅库。 MoviePy可以读取和写入所有最常见的音频和视频格式,包括GIF,并在Windows / Mac / Linux上运行,使用Python …

《新摩登时代》:卓别林演绎共识与同步流程优化

FISCO BCOS是完全开源的联盟区块链底层技术平台&#xff0c;由金融区块链合作联盟(深圳)(简称金链盟)成立开源工作组通力打造。开源工作组成员包括博彦科技、华为、深证通、神州数码、四方精创、腾讯、微众银行、亦笔科技和越秀金科等金链盟成员机构。 代码仓库&#xff1a;htt…

卓别林论Scrum价值观:当我真正开始爱自己

As I began to love myself 当我真正开始爱自己&#xff0c; I found that anguish and emotional suffering are only warning signs that I was living againstmy own truth. 我才认识到&#xff0c;所有的痛苦和情感的折磨&#xff0c;都只是提醒我&#xff1a;我的生活违背…

当我开始爱自己——卓别林

当我真正开始爱自己&#xff0c; 我才认识到&#xff0c;所有的痛苦和情感的折磨&#xff0c; 都只是提醒我&#xff1a;活着&#xff0c;不要违背自己的本心。 今天我明白了&#xff0c;这叫做 『真实』。 当我真正开始爱自己&#xff0c; 我才懂得&#xff0c;把自己的…

前端每日挑战の纯CSS画卓别林

前端每日挑战の纯CSS画卓别林 内容摘要内容学习代码 内容摘要 伤心啊&#xff0c;写了好几天博客没人看~不过没关系&#xff0c;写博客的主要目的还是为了技术积累。在segmentFault上看到有前端每日专栏&#xff0c;觉得不错&#xff0c;正好css基础还不够巩固决定跟着该专栏每…

程序员与卓别林

时代变迁&#xff0c;许多电影已经过时了&#xff0c;被人们遗忘了&#xff0c;然而&#xff0c;总有几部电影&#xff0c;还留着人们的记忆中。因为人们认为&#xff0c;它们具有不可磨灭的精神价值。这些电影&#xff0c;就是我们常说的经典电影。《摩登时代》&#xff0c;就…

FISCO BCOS 《新摩登时代》:卓别林演绎共识与同步流程优化

作者&#xff1a;石翔&#xff5c;FISCO BCOS 核心开发者 共识与同步的流程优化&#xff0c;是FISCO BCOS性能优化迈开的第一步。仅依靠这一流程优化&#xff0c;就给系统TPS带来可观的1.75倍提升。但这不是目的&#xff0c;其目的在于确定了共识的主导地位&#xff0c;排除了…

脏话越多,代码越好!

&#x1f447;&#x1f447;关注后回复 “进群” &#xff0c;拉你进程序员交流群&#x1f447;&#x1f447; 作者丨程序员月亮 来源丨了不起的程序员&#xff08;ID&#xff1a;great_developer&#xff09; 你好呀&#xff0c;我是月亮&#xff0c;一个90后的老程序员啦~ 平…

基于langchain 的文档问答 最佳实践(附源码)

文档问答的原理 文档读取并切割&#xff0c;用句向量 向量化&#xff0c;存入向量数据库问题向量化&#xff0c;在向量数据库中进行相似性检索&#xff0c;并存出top K把问题和top K 答案组成 prompt 并发给大模型&#xff0c;等大模型答案 这里面涉及到的技术点有&#xff1a…

chatgpt赋能python:Python为什么闪退?

Python为什么闪退&#xff1f; Python作为一种高级编程语言&#xff0c;已经赢得了世界各地许多开发者的青睐。但是&#xff0c;有时候Python会因为各种原因而突然闪退&#xff0c;给开发者带来极大的困扰。那么&#xff0c;Python为什么会闪退呢&#xff1f; 1. 内存泄漏 内…

Trexquant | 量化多岗位招聘(全职+实习)

量化投资与机器学习微信公众号&#xff0c;是业内垂直于量化投资、对冲基金、Fintech、人工智能、大数据等领域的主流自媒体。公众号拥有来自公募、私募、券商、期货、银行、保险、高校等行业30W关注者。 具体投递方式 投递邮箱 tqchina_resumetrexquant.com 简历命名 岗位-姓名…

京东各大城市内推岗位(2021.2.7更)

北京&#xff1a; 上海&#xff1a; 广东&#xff1a; 四川&#xff1a; 重庆&#xff1a; 暂无 杭州&#xff1a; 暂无 陕西&#xff1a; 湖北&#xff1a; 湖南&#xff1a; 暂无 岗位每周更新一次 因为内推系统只能以省份维度查看&#xff0c;想了解具体城市和岗…

北京内推 | 京东营销与商业化中心招聘NLP算法工程师/实习生

合适的工作难找&#xff1f;最新的招聘信息也不知道&#xff1f; AI 求职为大家精选人工智能领域最新鲜的招聘信息&#xff0c;助你先人一步投递&#xff0c;快人一步入职&#xff01; 京东 京东营销与商业化中心&#xff08;原商提广告部&#xff09;成立于2014年初&#xff0…

【CSDN雇主招聘】深信服科技带着高薪岗位JD和公司周边来啦

为了帮助企业更好的应对用人难的挑战&#xff0c;CSDN面向所有企业全新升级了CSDN2022雇主品牌计划&#xff0c;在企业发展、吸引人才、连接人才、宣传公司多个维度提供专属的支持。 ————本次为深信服科技专场———— 直播主题&#xff1a;《CSDN雇主品牌-深信服招聘专场…

【名企招聘】4月20日19点,Thoughtworks专场招聘,众多岗位JD解读,总有适合你的岗位~

为了帮助企业更好的应对用人难的挑战&#xff0c;CSDN面向所有企业全新升级了CSDN2022雇主品牌计划&#xff0c;在企业发展、吸引人才、连接人才、宣传公司多个维度提供专属的支持。 ————本次为Thoughtworks专场———— 直播主题&#xff1a;《CSDN雇主品牌-Thoughtwork…