重学操作系统(四)
前言
这篇文章,记录下存储器相关的一些知识,涉及到L1 Cache,SSD,内存的一些问题。接下来还是贯穿全文的一个问题
SSD、内存和 L1 Cache 相比速度差多少倍?
存储器分级
为什么有存储器分级策略
因为我们希望的存储器是,体积小,空间大,功耗低,散热好,速度快。但是这种存储器是不存在的,现阶段,没有存储器能同时满足所有优点。
存储器分级策略

上图很明显看出,存储器主要分6级。
寄存器
紧挨着CPU的控制单元和逻辑单元,所使用的材料也是最快的。存储速度快,能耗高,产热大,花费高。所以数量不能很多。
32位CPU中寄存器大多能存4个字节的内容
64位CPU中寄存器大多能存8个字节的内容
寄存器访问很快,一般要求半个CPU周期内完成读写。
L1-Cache
L1 缓存在CPU中,虽然它离CPU更近,但是它造价低,通常L1缓存大小在几十Kb到几百Kb,读写速度大概是2-4个CPU周期。
L2-Cache
L2缓存也在CPU中,但是比L1缓存离CPU远。它大小比L1缓存大,能达到几M,速度是10 - 20个CPU周期。
L3-Cache
L3缓存在CPU中,比L2缓存离CPU更远。大小通常大于L2缓存,可以达到十几或者几十M,读写时间是20 - 60个CPU周期。
内存
内存主要材料是半导体硅,主要插在主板上,距离CPU有一定的距离,需要总线,才能和CPU连接。它体积大,造价远低于前面的存储器。内存可以达到几G到几T这个范围的存储空间。它的读写速度是200 - 300个CPU周期
SSD和硬盘
SSD:固态硬盘,结构类似内存,但是断电后数据能保存。内存,缓存,寄存器,断电后数据消失。内存读写速度比SSD快了10 - 1000倍,而比硬盘快了大概100万倍。因此SSD逐渐取代硬盘。
当CPU需要内存中的某个数据,查询流程是:
寄存器(如果没有)-> L1缓存(如果没有)-> L2缓存(如果没有)-> L3缓存(如果没有)->内存
缓存条目结构
无论内存还是缓存,都是线性存储器,数据一个挨着一个存储。如果内存是一列表格,那么缓存是一个多列表格,每个表格中的每一行,叫做缓存条目。
方案
数学方法:
比如100个内存地址,但是10个缓存条目。内存地址编号0 - 999,缓存条目编号0 - 9。比如701编号的内存,用数学方法,通过”地址 % 缓存条目数”这种方式,确定它的缓存条目。
指令预读
由于CPU执行指令速度很快,一般2 - 6个周期能执行完毕,但是CPU读取内存速度,要200 - 300个周期,因此,CPU不能在内存中读一条指令就执行,如果这样,每个指令执行要200 - 300个周期。
解决方法:
将L1缓存分为指令区和数据区,为了避免数据缓存覆盖指令缓存。然后CPU把内存中的指令预读几十或者上百条,存到L1缓存。L1缓存读写速度是2 - 4个周期,因此可以跟上指令执行的速度。L2和L3不协助处理指令预读的问题,因此它们不需要被分为指令区和数据区。
缓存的命中率
和缓存命中相反的是,miss,缓存穿透。一般三级缓存的命中率在95%,只有大概5%的内存读取会穿透。
缓存置换
L1缓存满了,再次读内存,需要将旧条目移除,新条目存入,就叫缓存置换。
总结
回到开头的问题,我们可以得到,内存比SSD快10 - 1000倍,L1 Cache比内存快100倍。因此L1 Cache比SSD快1000 - 100000倍。
思考
假设有一个二维数组,共有1M个条目,如果遍历数组,是逐行遍历还是逐列遍历?
Answer:
逐行遍历,因为二维数组是每行是一个一维数组。元素存在一维数组内是连续的,因此逐行遍历,能一次将这些连续地址加载到缓存,提高了缓存命中率。并且逐行遍历,内存页交换次数会增加很多(最差情况,每遍历一个元素就交换一次)。这种情况可以通过增大物理内存解决。