1.1 Cache不可不察也

2023-10-25 17:18
文章标签 cache 1.1 不可不

本文主要是介绍1.1 Cache不可不察也,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在现代处理器中,CacheHierarchy一般由多级组成,处于CPU和主存储器之间,形成了一个层次结构,这个层次结构日趋复杂。Intel甚至放弃使用阿拉伯字母对Cache的各级层次编号,而直接使用LLC(Last-Level Cache)MLC(Medium-Level Cache)这样的术语。

变化的称呼表明了一个事实,Cache层次结构在整个处理器系统中愈发重要,也越发复杂。Sandy Bridge处理器大约使用了十亿个晶体管,在其正中不再是传统的CPU,是Ring Bus包裹着的最后一级Cache [1]

1.1 <wbr>Cache不可不察也

处理器的制作过程异常复杂。在人类历史上,其设计难度只有古埃及的金字塔可以与其媲美,即便是胡夫金字塔也只使用了230万个巨石,几十万个劳工而已。现代CPU的所耗的资源何止这些数字。在处理器这座金字塔中,Cache层次结构是最基本的框架。

几千年前,孙子曾经说过,“兵者,国之大事,死生之地,存亡之道,不可不察也”。对于有志于站在金字塔顶峰的,即便目标只有半山腰的系统程序员,也是Cache,不可不察也。在IntelValues->Discipline中有一句话“Pay attention to detail”。

但是不要忘记Devil is in thedetail。准备深入理解Cache层次结构的读者需要时刻提醒自己真正了解什么是细节之后,才会重视细节,才能够避免因为忽视细节而引发的灾难。重视细节这个品质与你是否足够细心没有必然联系。

我们回到公式13,简单探讨计算Hit timeMiss RateMiss Penalty这三个参数时所需要考虑的因素和相关的环境。

似乎Hit Time参数最容易获得。我们很快就可以从CPU的数据手册中找到各级Cache Hit后的访问时间,并从L1 Cache的访问时间开始计算Hit Time。可能我们上来就错了,现代处理器大多使用了Store-LoadForwarding技术。存储器读操作首先要查询的并不是L1 Cache,是在更前面执行的,还没有来得及提交的Store结果,这些结果保存在一段数据缓冲中,这个数据缓冲也是一种Cache,不过比L1 Cache更加快速一些,也更接近CPU

除了数据Cache,在现代处理器中,在指令Cache前还有一个Line-Fill BufferSandy Bridge微架构中还含有一个μops Cache[1],计算指令CacheHit延时也没有想象中容易。精确计算指令与数据Cache Hit的延时需要注意很多细节。简而言之,在处理器系统存储层次中,L1 Cache并不是最快的,也不是第一级。如果进一步考虑到Load Speculation使用的各类算法和命中率,Hit Time参数并不容易计算清楚。

即便不考虑这些较为复杂的细节,我们仅从L1 Cache开始,Hit Time参数也很难用简单的公式描述。在单处理器环境中,L1 Miss后会逐级查找下级Cache,直到主存储器。但是在多处理器内核环境中,情况复杂得多,一次存储器访问在自己的内核中没有命中,可能会在其他内核的Cache中命中,在其他内核的Cache中命中后,又存在数据如何传递,延时如何计算这些问题。说清楚这些问题并不容易。如果我们再进一步讨论多个SMP系统间Cache的一致性,这个Hit Time的计算就更加复杂。我只能选择放弃在这一节内,能够清楚地描述如何计算Hit Time这个参数。

Miss Rate参数更加难以琢磨。我们真的可以用VtunePerf这样的工具精确计算出哪怕是单个任务的Miss Rate这样的参数吗,用这样的工具得到的统计数值有什么用途。同一片树叶,有的人一叶障目,有的人一叶知秋。不要为一叶障目而苦恼。多看几片后,必会发现春天的到来,也不要为一叶知秋而骄傲,少看几片,终会被最后一片树叶阻隔。

Miss Penalty参数的计算仿佛容易一些。最糟糕的情况莫过于CPU从主存储器中获取数据。我们可以将环境进一步简化,以便于读者计算这个参数。我们可以不讨论SMP系统间的Cache一致性,甚至不讨论SMP之内的Cache一致性,仅讨论单处理器。即便如此Miss Penalty参数也不容易轻易计算,即便在这种情况之下,我们只讨论存储器读。

我们忽略微架构在Cache使用的各类Queue,让存储器读操作首先对L1 Cache进行尝试。如果没有命中这级Cache,这次数据访问一定可以到达L2 Cache吗,如果不是L2 Cache,又是哪一级Cache。这一切由L1L2 Cache的关联结构决定。在一个处理器系统中,L1L2 Cache之间可能是Inclusive,也可能是Exclusive。如果是Inclusive,存储器读操作将接着尝试L2 Cache,如果不是将会跨越这级Cache。事实并非如此简单,L1L2 Cache并不会直接相连,之间依然存在着许多Buffer

历经千辛万苦,数据访问最终到达最后一级Cache,如果没有命中,就可以从主存储器中获得数据。在这种情况之下,我们仿佛可以计算出最恶劣情况之下的Miss Penalty。但是这只是噩梦的开始。在现代处理器系统中,每一次存储器读写指令,都是由若干个步骤组成,这些步骤间具有相互联系,如果进一步考虑Memory Consistency层面,所涉及到的同步操作更多一些,这些操作并不能用几句话概括。

我们抛开这些复杂话题,讨论在L1L2 Cache Miss之后从存储器获得数据这个模型。存储器读从存储器获得数据仅是一次读访问的步骤。从主存储器获得的宝贵数据不会轻易丢失,会存放在Cache中,需要将这些数据存放到哪一级Cache最为合理,LLCMLCs还是FLC

在一个正常运行的系统中,在每一个Cache Block中存放的数据都是有用的。新数据存放通常意味着旧数据的淘汰。值得思考的是如何进行这些淘汰操作,使用什么策略进行淘汰。从L1 Cache中淘汰的数据虽然暂时没有用途,但是不意味着可以轻易丢失,是否应该先进入到L2 Cache暂存。采用这种策略时,L2 Cache也需要相应的进行淘汰操作。

从上文的描述可以看到,一个简单的存储器读访问带来了一系列的问题。我们首先需要为这次存储器读做基础的准备,然后进行真正的存储器读,读完成之后,还有复杂的扫尾工作。貌似容易计算的Miss Penalty参数即便在简化到了不能再简化的现代处理器系统中,也很难计算清楚。

我们还没有讨论存储器写对Cache Block的的污染与破坏,写操作可能会改变Cache Block的状态,使存储器读操作更加举步维艰,写操作还会带来很多Bus Traffic,这些Traffic加大了存储器读的Miss Penalty,我们没有讨论多处理器内核环境下的Cache Coherence

我们依然忽略了一个更加基本的细节,虚实地址转换。在现代操作系统中运行的任务,没有哪个任务可以直接使用PhysicalAddress(PA),使用更多的是EffectiveAddress(EA)。在多数处理器系统中,EA首先被转换为VirtualAddress(VA),之后再转化为PA。处理器微架构在更多的场景中直接使用的是PA,不是VA更不是EA

虚拟化技术的引入,在略微有些复杂的VAPAEA的基础上又引入了MPA(Machine PhysicalAddress)GPA(Guest PhysicalAddress),带来了一系列地址Mapping机制,中断重定向等内容。虚拟化还带来了IOMMUI/O虚拟化技术。为了能够在最小的篇幅完成这篇文章,我们忽略虚拟化技术,专注最基础的虚实地址转换。

这篇关于1.1 Cache不可不察也的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/284031

相关文章

usaco 1.1 Broken Necklace(DP)

直接上代码 接触的第一道dp ps.大概的思路就是 先从左往右用一个数组在每个点记下蓝或黑的个数 再从右到左算一遍 最后取出最大的即可 核心语句在于: 如果 str[i] = 'r'  ,   rl[i]=rl[i-1]+1, bl[i]=0 如果 str[i] = 'b' ,  bl[i]=bl[i-1]+1, rl[i]=0 如果 str[i] = 'w',  bl[i]=b

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

1.1 Avtivity的生命周期全面分析

本文将Activity的生命周期分为两部分内容,一部分是典型情况下的生命周期,另一部分是异常情况下的生命周期。所谓典型情况下的生命周期,是指在有用户参与的情况下,Activity所经过的生命周期的改变;而异常情况下的生命周期是指在Activity被系统回收或者由于当前设备的Configuration发生改变从而导致Activity被销毁重建,异常情况下的生命周期的关注点和典型情况下略有不同。 1

[项目][CMP][Thread Cache]详细讲解

目录 1.设计&结构2.申请内存3.释放内存4.框架 1.设计&结构 Thread Cache是哈希桶结构,每个桶是一个按桶位置映射大小的内存块对象的自由链表 每个线程都会有一个Thread Cache对象,这样每个线程在这里获取对象和释放对象时是无锁的 TLS – Thread Local Strorage Linux gcc下TLSWindows vs下TLS

[项目][CMP][Central Cache]详细讲解

目录 1.设计&结构2.申请内存3.释放内存4.框架 1.设计&结构 Central Cache也是一个哈希桶结构,它的哈希桶的映射关系跟Thread Cache是一样的不同的是它的每个哈希桶位置挂的是SpanList链表结构(带头双向循环链表),不过每个映射桶下面的span中的大内存块被按映射关系切成了一个个小内存块对象挂在span的自由链表中 8Byte映射位置下面挂的是

不可不说的Java锁事

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 大数据技术与架构 点击右侧关注,大数据开发领域最强公众号! 暴走大数据 点击右侧关注,暴走大数据! 前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。 Java中

2020 1.1版本的idea中git的使用场景

1、克隆项目 File-->New-->Project from Version Control 2、拉取远程的分支到本地 右下角-->(Remote Branches)选定分支-->checkout 3、将master分支更新的代码合并至bry分支并提交到远程仓库    (目的:实时与master的最新代码保持一致) 右下角-->(Local Branches)checkout br

Python二级知识点--1.1(计算机系统)

以下内容,皆为原创,感谢大家的关注和点赞。 考点:在执行指令的过程中,CPU不经过总线能直接访问的是寄存器 在执行指令的过程中,CPU 不经过总线能直接访问的是内部寄存器。   CPU 内部的寄存器通常与 CPU 的控制单元、算术逻辑单元等紧密集成,它们之间通过内部高速的数据通路进行连接,无需经过外部总线。   这是因为内部寄存器的访问速度对于 CPU 的高效运行至关重要。在指令执行的过程

LRU算法 - LRU Cache

这个是比较经典的LRU(Least recently used,最近最少使用)算法,算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。 一般应用在缓存替换策略中。其中的”使用”包括访问get和更新set。 LRU算法 LRU是Least Recently Used 近期最少使用算法。内存管理的一种页面置换算法,对于在内存中但又不用的

Fast Image Cache

https://github.com/path/FastImageCache   Fast Image Cache is an efficient, persistent, and—above all—fast way to store and retrieve images in your iOS application. Part of any good iOS applica