性能优化!突破性能瓶颈的尖兵 CPU Cache
今天我们来介绍计算机的储存器之一,CPU 高速缓冲存储器也叫高速缓存,CPU Cache
缓存这个专业术语,在计算机世界中是经常使用到的。它并不是 CPU 所独有的,比如 cdn 缓存网站信息,浏览器缓存网页的图像视频等,但本文讲述的是狭义 Cache,主要指的是CPU Cache
,本文将其简称为"缓存"或者"Cache"
计算机性能的瓶颈
在冯诺依曼架构下,计算机存储器是分层次的,存储器的层次结构如下图所示,是一个金字塔形状的东西。从上到下依次是寄存器、缓存、主存(内存)、硬盘等等
离 CPU 越近的存储器,访问速度越来越快,容量越来越小,每字节的成本也越来越昂贵
比如一个主频为 3.0GHZ 的 CPU,寄存器的速度最快,可以在 1 个时钟周期内访问,一个时钟周期(CPU 中基本时间单位)大约是 0.3 纳秒,内存访问大约需要 120 纳秒,固态硬盘访问大约需要 50-150 微秒,机械硬盘访问大约需要 1-10 毫秒,最后网络访问最慢,得几十毫秒左右。
这个大家可能对时间不怎么直观,那如果我们把一个时钟周期如果按 1 秒算的话,那寄存器访问大约是 1s,内存访问大约就是 6 分钟 ,固态硬盘大约是 2-6 天 ,传统硬盘大约是 1-12 个月,网络访问就得几年了!我们可以发现 CPU 的速度和内存等存储器的速度,完全不是一个量级上的。
电子计算机刚出来的时候,其实 CPU 是没有缓存 Cache 的,那个时候的 CPU 主频很低,甚至没有内存高,CPU 都是直接读写内存的
随着时代的发展,技术的革新,从 1980 年代开始,差距开始迅速扩大,CPU 的速度远远超过内存的速度,在冯诺依曼架构下,CPU 访问内存的速度也就成了计算机性能的瓶颈!!!
DRAM 为内存颗粒,也叫动态随机存取存储器, 图片来源于:How L1 and L2 CPU Caches Work, and Why They're an Essential Part of Modern Chips
为了弥补 CPU 与内存两者之间的性能差异,也就是要加快 CPU 访问内存的速度,就引入了缓存CPU Cache
,缓存的速度仅次于寄存器,充当了 CPU 与内存之间的中间角色
缓存及其发展历史
缓存CPU Cache
用的是 SRAM(Static Random-Access Memory)的芯片,也叫静态随机存储器。其只要有电,数据就可以保持存在,而一旦断电,数据就会丢失。
CPU Cache 如今通常分为大小不等的 3 级缓存,分别是 L1 Cache、L2 Cache 和 L3 Cache,
我们可以发现越靠近 CPU 核心的缓存,其访问速度越快,其大小越来越小,其制造成本也越昂贵,常见的 Cache 典型分布图如下:
回顾 Cache 发展历史,我们可以发现 Cache 其实一开始并不是在 CPU 的内部,我们这里以 intel 系列为例
在 80286 之前,那个时候是没有缓存 Cache 的,那个时候的 CPU 主频很低,甚至没有内存高,CPU 都是直接读写内存的
从 80386 开始,这个 CPU 速度和内存速度不匹配问题已经开始展露,并且差距开始迅速扩大,慢速度的内存成为了计算机的瓶颈,无法充分发挥 CPU 的性能,为解决这个问题,Intel 主板支持外部Cache
,来配合 80386 运行
80486 将L1 Cache(大小8KB)
放到 CPU 内部,同时支持外接 Cache,即 L2 Cache(大小从 128KB 到 256KB),但是不分指令和数据 Cache
虽然L1 Cache
大小只有 8KB,但其实对那时候 CPU 来说够用了,我们来看一副缓存命中率与 L1、L2 大小的关系图:
从上图我们可以发现,增大 L1 cache 对于 CPU 来说好处不太明显,缓存命中率并没有显著提升,成本还会更昂高,所以性价比不高。
而随着 L2 cache 大小的增加,缓存总命中率会急剧上升,因此容量更大、速度较慢、更便宜的 L2 成为了更好的选择
等到 Pentium-1/80586,也就是我们熟悉的奔腾系列,由于 Pentium 采用了双路执行的超标量结构,有 2 条并行整数流水线,需要对数据和指令进行双重的访问,为了使得这些访问互不干涉,于是 L1 Cache 被一分为二,分为指令 Cache 和数据 Cache(大小都是 8K),此时的 L2 Cache 还是在主板上,再后来 Intel 推出了Pentium Pro/80686,为了进一步提高性能 L2 Cache 被正式放到 CPU 内部
后来 CPU 多核时代来临,Intel 的 Pentium D、Pentium EE 系列,CPU 内部每个核心都有自己的 L1、L2 Cache,但他们并不共享,只能依靠总线来传递同步缓存数据。最后 Core Duo 酷睿系列的出现,L2 Cache 变成多核共享模式,采用 Intel 的“Smart cache”共享缓存技术,到此为止,就确定了现代缓存的基本模式
如今 CPU Cache 通常分为大小不等的 3 级缓存,分别是 L1 Cache、L2 Cache 和 L3 Cache,L3 高速缓存为多个 CPU 核心共用的,而 L2 则被每个核心单独占据,另外现在有的 CPU 已经有了 L4 Cache,未来可能会更多
缓存如何弥补 CPU 与内存的性能差异?
我们可以思考一个问题:缓存是如何弥补 CPU 与内存两者之间的性能差异?
缓存主要是利用局部性原理,来提升计算机的整体性能。因为缓存的性能仅次于寄存器,而 CPU 与内存两者之间的产生的分歧,主要是二者存取速度数量级的差距,那尽可能多地让 CPU 去存取缓存,同时减少 CPU 直接访问主存的次数,这样计算机的性能就自然而然地得到巨大的提升
所谓局部性原理,主要分为空间局部性
与时间局部性
:
时间局部性:被引用过一次的存储器位置在未来会被多次引用(通常在循环中)。
空间局部性:如果一个存储器的位置被引用,那么将来他附近的位置也会被引用
缓存这里,会去把 CPU 最近访问主存(内存)中的指令和数据
,临时储存着,因为根据局部性原理,这些指令和数据在较短的时间间隔内很可能会被以后多次使用到,其次是当从主存中取回这些数据时,会同时取回与其位置相邻的主存单元的存放的数据 临时储存到缓存中,因为该指令和数据附近的内存区域,在较短的时间间隔内也可能会被多次访问。
那以后 CPU 去访问这些指令和数据时,首先去命中L1 Cache
,如果命中会直接从对应的缓存中取数据,而不必每次去访问主存,如果没命中,会再去L2 Cache
中找,依次类推,如果L3 Cache
中不存在,就去内存中找。
尾语
本文简单介绍了计算机性能瓶颈的原因,缓存及其发展历史,最后讲解了缓存弥补 CPU 和内存性能差异的原理,后面我们会继续更详细深入地介绍 Cache 的组织结构、缓存一致性,以及如何利用缓存提升我们代码的性能等
文章转载自:xiaoniuhululu
评论