课程链接:深入浅出计算机组成原理_组成原理_计算机基础-极客时间
目录
一、高速缓存
按照摩尔定律,CPU 的访问速度每 18 个月便会翻一番,相当于每年增长 60%。内存的访问速度每年只增长 7% 左右。而这两个增长速度的差异,使得 CPU 性能和内存访问性能的差距不断拉大。
从 CPU Cache 被加入到现有的 CPU 里开始,内存中的指令、数据,会被加载到 L1-L3 Cache 中,而不是直接由 CPU 访问内存去拿。在 95% 的情况下,CPU 都只需要访问 L1-L3 Cache,从里面读取指令和数据,而无需访问内存。这里我们说的 CPU Cache 或者 L1/L3 Cache,不是一个单纯的、概念上的缓存(比如之前我们说的拿内存作为硬盘的缓存),而是指特定的由 SRAM 组成的物理芯片。
按道理来说,循环 2 只访问循环 1 中 1/16 的数组元素,只进行了循环 1 中 1/16 的乘法计算,那循环 2 花费的时间应该是循环 1 的 1/16 左右。但实际上,循环 1 运行需要 50 毫秒,循环 2 只需要 46 毫秒(课程老师运行的结果)。这两个循环花费时间之差在 15% 之内。
其实,运行上面程序的时间主要花在了将对应的数据从内存中读取出来,加载到 CPU Cache 里。CPU 从内存中读取数据到 CPU Cache 的过程中,是一小块一小块来读取数据的,而不是按照单个数组元素来读取数据的。这样一小块一小块的数据,在 CPU Cache 里面叫作 Cache Line(缓存块)。
我们日常使用的 Intel 服务器或者 PC 里,Cache Line 的大小通常是 64 字节。循环 2 每隔 16 个整型数计算一次,16 个整型数正好是 64 个字节。于是,循环 1 和循环 2,需要把同样数量的 Cache Line 数据从内存中读取到 CPU Cache 中,最终两个程序花费的时间就差别不大了。
(一)Cache 的数据结构和读取过程
现代 CPU 进行数据读取的时候,始终会首先访问 Cache。只有在 Cache 中找不到数据才会去访问内存,并将读取到的数据写入 Cache 之中。当时间局部性原理起作用后,这个最近刚刚被访问的数据,会很快再次被访问。而 Cache 的访问速度远远快于内存,这样,CPU 花在等待内存访问上的时间就大大变短了。
那么CPU如何知道要要访问的内存数据,存储在 Cache 的哪个位置呢?
直接映射 Cache(Direct Mapped Cache):CPU 访问内存数据,是一小块一小块数据来读取的,首先拿到的是数据所在的内存块(Block)的地址。而直接映射 Cache 采用的策略是确保任何一个内存块的地址,始终映射到一个固定的 CPU Cache 地址(Cache Line)。而这个映射关系,通常用 mod 运算(求余运算)来实现。
实际计算中,有一个小小的技巧,通常我们会把缓存块的数量设置成 2 的 N 次方。这样在计算取模的时候,可