暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

探索CPU的缓存架构,及引申到缓存系统的设计(一)

云时代架构 2018-03-01
564

探索底层的意义

话说人们在1870年左右开始应用黄色火药,在1900年左右开始大量普及电动地铁,并建成了埃菲尔铁塔(1898)等伟大工程,但是军事技术的发展、革新最多的仅是二战前后的1936到1945的这几年时间,现在的军事技术也大都仅是对二战时的军事技术体系的深化,如自动步枪,喷气引擎,潜艇,坦克和反坦克等等。所以我们认为,高强度的行业竞争,带来其领域技术的深入发展,而因其深入的发展,其中的许多设计理念和产出,往往惠及了很多的民用领域,如复杂的涡轮增压技术是二战战斗机的标配,现在也经过简化,惠及到民用汽车领域。

而现在信息技术领域中白热化的竞争莫过于Intel和AMD之间的蓝红之争,其竞争让CPU的设计和架构经过千锤百炼,是一个现代人类设计和实践的结晶。因此我们探究一下CPU底层的实现,其中的思路和理念,特别是现在多核心CPU的设计,也会对我们的高性能系统,以及分布式系统的设计和使用有很多借鉴和帮助。

另外其实人们也发现往往一些带有分形的东西,其不仅广泛存在,而且也代表着很多我们未知的合理结构,如人们所说的黄金分割,宇宙及黑洞等,其也都和分形有关联,分形可以简单理解为不断深入的底层构成,和其上层构成有结构上的相似。因此我们探究底层的设计,也对我们上层系统的设计有一定的参考和指导作用。

CPU的缓存结构简介

如下图所示是Intel的Skylake的CPU架构,我们可以看到缓存被分为L1、L2、L3这3层,CPU在运行中首先使用自己的寄存器,然后使用速度更快的L1缓存,其中:L1D缓存数据;L1I缓存指令;L1缓存和次快的L2同步数据;L2缓存和L3缓存同步数据(这里L2和L3按照内核数量做了等分,分给各个内核使用),我们可以简单地认为L3和内存同步数据。

Intel的PPT 中Skylake的缓存示意图的截图

为什么会有这么多级的缓存呢?因为每级缓存的速度差异很大,越快的缓存容量越小,因此CPU把缓存分成多级,每一级作为上一级的缓存。(其实在多核的情况下访问缓存会有一些同步问题,我们在下文讨论)

CPU的缓存性能参考

而我们可以认为目前CPU的缓存性能差异如表所示(参考了卡耐基梅隆大学在2014年的教案等)。

缓存性能表

在上表中要注意以下内容:

1. L1、L2、L3的最小读写单位是64bit(8字节)。

2. L2的周期已包含L1(miss)的周期,L3的周期已包含L2(miss)的周期。

3. 内存访问应该还有TLB(虚拟地址页表缓存)的miss的情况,会增加少量周期。

4. 其实CPU的寄存器的整体大小为2KB左右,在64位下除了RAX、RBX、RCX、RDX、RSI、RDI、RSP、RBP、R8-R15这16个通用寄存器,如Intel还大概有:MMX:80bit X 8,ZMM(YMM,XMM):512bit X 32等寄存器,还有控制:64bit X 16,调试:64bit X 16,以及其他零散分类下及系统自用的若干。

因为这些缓存和内存在性能上的差异,所以对CPU的密集运算则是越少访问内存越好,比如在发生一次CAS操作时,如果这个内存访问能命中L2缓存,则还是比较高效的;但是如果L2 miss 连同 L3 miss ,则会变成一次读内存的重操作,影响并发的性能(约100ns的耗时),同理,对于正常的锁的操作,缓存miss时会耗时较多(约200ns的耗时)。

当前CPU的架构图

下面是Intel的Skylake 的架构图,与Sandy Bridge 的架构图,和AMD的ZEN 的架构图。

Intel的Skylake的架构图

Intel的Sandy Bridge 的架构图

AMD的ZEN 的架构图

Intel和AMD的CPU的架构图虽然看着差异挺大,但它们的大结构其实是一样的,大概都分为3个模块。

1. 前端执行(front end):对应Intel图的上面及对应AMD图上面;这个是L1指令cache处理指令解码(DECODE),分支预测,执行队列,调度器,等这些指令功能。

2. 计算:对应INTEL图的左下及对应AMD图的中间;这个就是整数计算单元和浮点计算单元。

3. 缓存/内存:对应INTEL图的右下及对应AMD图的下面;这个就是内存控制器(内存读写控制器及队列,以及TLB(内存页表的虚拟地址转换缓存))及L1数据缓存和L2缓存。

从这些图上我们可以看出,L1命令缓存AMD的Zen是64KB,而Intel是32KB;L2缓存AMD的Zen是512KB,Intel是256KB,这个和CPU型号也有关系,但还是说明同一代下AMD的CPU在一些配置上更优一些。

这里也说下,网上流传说,在AMD的Zen之前Intel的CPU的强大的浮点功能(以及除法器),是Intel在跑分上胜利的其中一个重要因素,AMD认为都有显卡了,显卡浮点计算的能力非常强大,因此CPU不需要太强的浮点功能了……。

再有我们在看AMD的PPT时会发现,除了L1数据缓存到寄存器堆(register

file)还有个AGU到load/store queues模块的箭头,这里可能感觉比较奇怪,其实这个AGU的组件AMD和Intel都有,Intel的没有画出(之前的架构PPT里有,现在应该属于Load Store Data这,但没有画出),这个全称是Address Generation Unit,用来加速计算实际的物理地址,以及计算数组中的地址等。(另外,其实大家知道应用程序中的内存地址对CPU和操作系统来讲都是比较麻烦的虚拟地址)。下图是AMD的缓存/内存单元单元的一个展开图(图中L1数据缓存上的To Ex是到整数计算单元,To Fp是到浮点计算单元)。如图

AMD的缓存/内存部分的展开图

CPU缓存的使用

上面介绍了CPU整体的架构图,以及缓存在CPU架构图中的位置,这里先介绍下CPU在单核环境下的多级缓存的架构。

现在CPU都流行多核芯的架构,而我们先看其中的一个核心对缓存操作的流程,我们可以整体认为:当核心(Core)访问(读或写)L1缓存时没有命中(miss)则访问L2缓存和L3缓存,在L3缓存也没有命中时才操作内存。多级缓存在独占(exclusive)模式下,L1缓存中通过LRU策略逐出的数据会到L2,在L2中逐出的会到L3,在L3中逐出的有写入/修改的数据则同步到内存。

缓存的操作的最小单元我们可以叫缓存单元,英文是cache line,每个缓存单元缓存64bit(8Byte)的数据,访问缓存时通过内存单元的物理地址。另外我们常看到8WAY,16WAY这种来描述缓存,其实缓存的在使用时是个类似二维数组的形式,这里的列就是WAY,如8WAY,就是8列。访问时通过物理地址的高位和中位从列(WAY)和行(SET)中命中一个缓存单元(cache line,也可以翻译成缓存行),可参考下图示意。

AMD文档中的缓存操作示意

缓存单元因其一次必须操作连续的8Byte的数据,但是我们不希望类似下面这样的情况,如两个相邻的整型(4Byte)数据会同时被多个CPU核心进行频繁修改,而其都在一个缓存单元内,其每次修改都会触发我们后面讲的核心的缓存到内存的同步问题。

我们先看看具体读写命中和未命中的情况:

1. 缓存没有命中的情况:

a). 对于单核心的读,读操作会先检查缓存,在缓存中没有数据时会载入数据到缓存(cache line fill)中。

b). 对于单核心的写,其同读操作,会先检查缓存,在缓存中没有数据时会载入数据到缓存中,然后执行写操作,这里写操作只是简单的写了载入过来的缓存,并不同步到内存(这里需要注意,按照Intel的开发文档,老的Pentium默认的情况是在缓存miss后写操作直接写内存,而不是载入数据到缓存后写缓存)。

2. 缓存命中的情况:

a). 如果读命中(cache hit),则直接使用数据;

b). 如果这里是写操命(write hit)时则也是直接操作缓存,而不主动同步到内存。

我们也看看CPU的缓存的使用流程:

1. CPU的前端解析L1命令缓存中的指令进行预测和乱序执行等

2. 通过这些指令,计算单元具体处理从L1数据缓存到寄存器中的数据的计算

3. 将计算的结果更新到L1数据缓存,若要同步缓存中的数据到内存,则通过硬件实现的写缓存逻辑(write buffers)可靠地异步刷新数据到系统总线及内存(可理解为通过一个消息队列写)。

这里可以看参考下图所示。

缓存相关流程,取自AMD技术文档

这里则是整个单核心的的流程,我们注意到,CPU通过缓存提高性能的一个关键要点是在写的情况下只写缓存,不同步缓存数据到内存。


推荐一起学习《分布式服务架构:原理、设计与实战》一书,它是一本不可多得的理论与实践相结合的架构秘籍,是作者多年工作经验积累的结晶。京东购买请扫描下方二维码。




如果你想成为优秀的架构师

在【云时代架构】精品群免费进!


我在【云时代架构】技术社区,你在哪里?


还等什么,赶快加入【云时代架构】技术社区!

请猛扫下面二维码。


云时代架构



做互联网时代最适合的架构

开放、分享、协作

快速关注,请猛扫下面二维码!


  

简书博客                      云时代架构


文章转载自云时代架构,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论