计算机原理(四) - 指南
2025-09-13 14:09 tlnshuju 阅读(4) 评论(0) 收藏 举报计算机原理系列
欢迎大家关注「海拉鲁知识大陆」 多交流不迷路
计算机原理(四)
今天大家继续聊聊计算机内存这块,内存有SSD、内存和 L1 Cache相比速度差多少呢?
1. 为什么存储器会有分级策略?
从需求上讲,大家肯定是希望存储器速度快、体积小、空间大、能耗低、散热好、断电信息不丢失。但现实很难把所有需求都实现。
- 假如一个存储器的体积小,那它存储空间就会受到制约。
- 假如一个存储器电子元件密度很大,那散热就会有问题。因为电子元件都会产生热能,所以电子元件非常集中的CPU,就需要单独的风扇或者水冷帮助电子元件降温。
- 假如一个存储器离 CPU 较远,那么在传输过程中必然会有延迟,因此传输速度也会下降。
2. 存储器分级策略
综上需要存储器来解决所有的需求,那就必须分级。
根据资料的利用频率使用不同的存储器:高频使用的数据,读写越快越好,因此用最贵的材料,放到离 CPU 最近的位置;使用频率越低的素材,大家放到离 CPU 越远的位置,用越便宜的材料。就是一种可行的方案,就
通常我们把存储器分成这么几个级别:
- 寄存器;
- L1-Cache;
- L2-Cache;
- L3-Cahce;
- 内存;
- 硬盘/SSD。
寄存器(Register)
寄存器紧挨着 CPU 的控制单元和逻辑计算单元,它所使用的材料速度也是最快的。,存储器的速度越快、能耗越高、产热越大,而且花费也是最贵的,因此数量不能很多。
寄存器的数量通常在几十到几百之间,每个寄存器可以用来存储一定字节(byte)的数据。比如:
- 32 位CPU中大多数寄存器可以存储4个字节;
- 64 位CPU中大多数寄存器可以存储8个字节。
寄存器的访问速度十分快,一般要求在半个CPU时钟周期内完成读写。比如一条要在4个周期内完成的指令,除了读写寄存器,还应该解码指令、控制指令执行和计算。假设寄存器的速度太慢,那4个周期就可能无法完成这条指令了。
L1-Cache
L1-缓存在CPU中,相比寄存器,虽然它的位置距离CPU核心更远,但造价更低。通常 L1-Cache大小在几十Kb到几百Kb不等,读写速度在2~4个CPU时钟周期。
L2-Cache
L2- 缓存也在CPU中,位置比L1-缓存距离CPU核心更远。它的大小比L1-Cache更大,具体大小要看CPU型号,有2M的,也有更小或者更大的,速度在10~20个CPU周期。
L3-Cache
L3-缓存同样在CPU中,位置比L2-缓存距离CPU核心更远。大小通常比L2-Cache更大,读写速度在20~60个CPU周期。L3缓存大小也是看型号的,比如i9的CPU有512KB的L1 Cache;有2MB的L2 Cache; 有16MB的L3 Cache。
内存
内存的主要材料是半导体硅,是插在主板上工作的。因为它的位置距离CPU有一段距离,所以必须用总线和CPU连接。缘于内存有了独立的空间,所以体积更大,造价也比上面提到的存储器低得多。个人笔记本上的内存是16G/32G,有些服务器的内存可以到几个T。内存速度大概在200~300个CPU周期之间。故而现在买电脑/笔记本知道看什么参数了吧
SSD 和硬盘
SSD也叫固态硬盘,结构和内存类似,它的优点在于断电后数据还在(数据持久化)。内存、寄存器、缓存断电后数据就没了。内存的读写速度比SSD大概快10~1000倍。
还有一种物理读写的磁盘,我们也叫作硬盘,它的速度比内存慢100W倍左右。速度太慢已经逐渐被SSD替代。
当CPU需要内存中某个数据的时候,如果寄存器中有这个数据,大家允许直接使用;如果寄存器中没有这个数据,我们就要先查询L1缓存;L1中没有,再查询L2缓存;L2中没有再查询L3缓存;L3中没有,再去内存中拿,内存没有再到磁盘了。
3. 缓存条目结构
上面介绍了存储器分级结构大概有哪些存储以及它们的特点,接下来聊聊缓存算法和数据结构的设计。比如CPU想访问一个内存地址,那么如何检查这个数据是否在L1-缓存中?
一个多列的表格,这个表格中的每一行叫作一个缓存条目。就是无论是缓存,还是内存,它们都是一个线性存储器,就是内容一个挨着一个的存储。如果我们把内存想象成一个只有1列的表格,那么缓存就
方案 1缓存本质上是一个Key-Value的存储,它的Key是内存地址,值是缓存时刻内存地址中的值。我们先思考一种简单的方案,一个缓存条目设计2列:
- 内存的地址Key列;
- 缓存的值Value列。
CPU读取到一个内存地址,我们就增加一个条目。当我们要查询一个内存地址的数据在不在L1-缓存中的时候,可以遍历每个条目,看条目中的内存地址是否和查询的内存地址相同。如果相同,我们就取出条目中缓存的值。
这个方法需要遍历缓存中的每个条目,所以计算速度会非常慢,在最坏情况下,算法需要检查所有的条目,所以这的方案不可取。
方案 2这里,大家许可用一个数学的方法。假如有1000个内存地址,但只有10个缓存条目。内存地址的编号是 0、1、2、3,…,999,缓存条目的编号是0~9。然后用数学方法把它映射到一个缓存条目,比如701整除10求余数,得到缓存条目为1。
然后再比较缓存条目中的第一列内存地址和查询的内存地址是否相同,就可以确定内存地址有没有被缓存。这里其实就是一种类似哈希表的方法:地址%10,其实就是一个简单的哈希函数。
4. 指令的预读
接下来再聊聊指令预读的问题。
之前我们有了解到CPU顺序执行内存中的指令,CPU执行指令的速度是非常快的,一般是2到6个CPU时钟周期;但内存的读写速度是十分慢的,大概有200~300个时钟周期。
这样就有一个非常麻烦的问题:CPU其实是不能从内存中一条条读取指令再执行的,如果这样做执行一条指令就需要200~300个时钟周期啊。
解决办法就是CPU把内存中的指令预读几十条或者上百条到读写速度较快的L1-缓存中,因为L1-缓存的读写速度只有2~4个时钟周期,是行跟上CPU的执行速度的。
如果数据和指令都存储在L1-缓存中,如果数据缓存覆盖了指令缓存,就会产生非常严重的后果。故而L1-缓存通常会分成两个区域,一个是指令区,一个是素材区。
L1-缓存分成了指令区和信息区,那L2/L3需不需要这样分呢?其实是不需要的。因为 L2和L3不需要协助处理指令预读的难题。
5. 缓存的命中率
接下来,对于L1/L2/L3加起来的缓存的命中率有多少?
命中就是指在缓存中找到需要的数据。和命中相反的是穿透,就是一次读取操作没有从缓存中找到对应的数据。(缓存雪崩 缓存穿透 缓存击穿是不是很熟悉的词出现了,不是同一件事哈,但是思维是一样的)
L1缓存的命中率大概在80%左右,L1/L2/L3加起来的命中率在95%左右。因此CPU缓存的设计还是相当合理的。只有5%的内存读取会穿透到内存,95%都能读取到缓存。缓存保证了很高的命中率。
6. 缓存置换问题
末了假如现在L1-缓存条目已经存满了,接下来CPU又读了内存,需要把一个新的条目存到L1-缓存中,既然有一个新的条目要进来,那就有一个旧的条目要出去。该时候我们就要求用一个算法去计算哪个条目应该被置换出去。这个疑问叫作缓存置换困难。这个其实就是涉及到进程的调度,后面再聊哈。
那么回顾一下前面提出的问题:SSD、内存和 L1 Cache 相比速度差多少倍?
【解析】因为内存比SSD快10到1000倍,L1 Cache比内存快100倍左右。因此L1 Cache比SSD快了1k~10w倍。所以SSD的潜力很大,好的SSD已经接近内存了。