相信大家一定都用过各种存储技术,比如mysql,mongodb,redis,mq等,这些存储服务性能有非常大的区别,其中之一就是底层使用的存储设备不同。作为一个程序员,你需要理解存储器的层次结构,这样才能对程序的性能差别了然于心。今天带大家了解下计算机系统存储器的层次结构。
首先了解下什么是存储器系统?
实质上就是一个具有不同容量、成本和访问时间的存储设备的层次结构。从快到慢依次为:CPU寄存器、高速缓存、主存、磁盘;
这里给大家介绍一组数据,让大家有一个更清晰的认识:
如果数据存储在CPU寄存器,需要0个时钟周期就能访问到,存储在高速缓存中需要4~75个时钟周期。如果存储在主存需要上百个周期,而如果存储在磁盘上,大约需要几千万个周期! -- 出自 CSAPP
接下来一起深入了解下计算机系统涉及的几个存储设备:
随机访问存储器(RAM)分为静态RAM (SRAM) 和动态RAM(DRAM)。SRAM的速度更快,但也贵很多,一般不会超过几兆字节,通常用来做告诉缓存存储器。DRAM就是就是我们常说的主存。
数据流是通过操作系统中的总线的共享电子电路在处理器和DRAM之间来来回回。每次CPU和主存之间的数据传送都是通过一系列复杂的步骤完成,这些步骤成为总线事务。读事务是将主存传送数据到CPU。写事务从CPU传送数据到主存。
总线是一组并行的导线,能携带地址、数据和控制信号。下图展示了CPU芯片是如何与主存DRAM连接的。
那么我们在加载数据和存储数据时,CPU和主存到底是怎样交互实现的呢?
首先来看一个基本指令,加载内存数据到CPU寄存器中:
movq A,%rax
将地址A的内容加载到寄存器%rax中,这个命令会使CPU芯片上称为总线接口(bus interface)的电路在总线上发起读事务,具体分为三个步骤:
随机访问存储器,有个缺点是当断电后,DRAM和SRAM会丢失它们的信息,因此为易失性存储。
磁盘是广为使用的保存大量数据的存储设备,目前我们家用电脑,动辄也都是1T的。它相比于基于RAM的只有几百或几千兆字节的存储器来说,虽然大但是读写性能差。时间为毫秒级,比DRAM读慢了10万倍,比SRAM慢了100万倍。
磁盘是由盘片构成的。每个盘片有两面。表面覆盖着磁性记录材料。盘片中央是一个可以旋转的主轴(spindle),它使盘片可以以固定的速率旋转,通常是5400~15000转每分钟,磁盘通常包含多个盘片,密封在一个容器内。
如上图,我们可以看到,表面被划分为很多同心圆,称为磁道。磁道又被划分为很多扇区,每个扇区具有相同的数据位(通常512字节)。扇区之间有间隙隔开,用来存储标识扇区的格式化位。
多个盘片封装在一起到一个容器中,就是我们平时用的硬盘,称为磁盘驱动器。
容量很好理解,就是磁盘一共可以存储的数据位。根据磁盘的构造,我们得出磁盘的容量由下面因素决定:
通过上面的了解,增加磁盘容量其实就是增加面密度,近些年面密度每隔几年就会翻倍。下面大家可以看一下这个磁盘容量的计算公式:
磁盘容量=字节数/扇区 * 平均扇区数/磁道 * 磁道数/表面 * 表面数/盘片 * 盘片数/磁盘
结合一个例子方便各位理解:
假如我们有一个磁盘,有5个盘片,每个扇区512字节,没个面20000条磁道,每条磁道 300 个扇区,那么容量计算为:
磁盘容量 = 512 * 300 * 20000 * 2 * 5 = 30720000000字节=30.72G
磁盘读写操作靠的是读写头来读写存储在磁性表面的位,它在传动臂的一端,通过这个传动臂沿着半径前后移动,从而读取不同的磁盘上数据,这个过程就成为寻道(seek)
通过上图可以清晰的了解到,在读取数据的时候,首先通过传动臂沿着半径将读写头移动到对应表面的磁道上,而表面一直在以固定的速率旋转,读取指定扇区的数据(磁盘是以扇区大小来读写数据)。因为对于数据访问来说,消耗时间主要集中在:寻道时间、旋转时间和传送时间。
这里给出一个书上写的结论,访问一个磁盘扇区中512字节的时间主要是寻道时间和旋转延迟。也就是访问扇区中第一个字节花费很长时间,剩下的几乎不用时间。
这里大家可能有疑问,CPU是如何读取磁盘的数据到主存的,这就需要了解I/O总线。他们通过多种适配器连接到总线,而I/O总线连接了内存和CPU。如下图所示:
也就是I/O总线连接各种I/O设备、主存等。
固态硬盘也就是俗称的SSD(Solid State Disk),是一种基于闪存的存储技术,目前常用的日常PC都用它来代替了磁盘,获取更快的速度。
SSD是内部由闪存构成,一个闪存由B个块的序列组成,每个块由P页组成。通常页的大小是512字节~4KB,块由32~128页组成,块的大小为16KB~512KB。
SSD的随机读比写快很多,是因为:
在大约进行100000次重复写之后,块会被磨损,不能在使用,所以这也是网上建议保存固态磁盘不要频繁格式化,作为系统盘的原因。
现在计算机频繁的使用基于SRAM的告诉缓存,为了弥补处理器-内存之间的差距,这种方法行之有效是因为局部性这个基本属性。
程序的局部性原理是指程序在执行时呈现出局部性规律,即在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域。局部性原理又表现为:时间局部性和空间局部性。时间局部性是指如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某数据被访问,则不久之后该数据可能再次被访问。空间局部性是指一旦程序访问了某个存储单元,则不久之后。其附近的存储单元也将被访问。
上面我们介绍了内存和磁盘的读取逻辑,因此一旦某个数据被访问过,很快的时间内再次被访问,则会有缓存等手段,提高访问效率。
因此我们程序中应该尊村下列普遍方法:
比如一个for循环,这是平时经常使用到的场景。假设它访问一个同一个数组元素,那么这个数组就是当前阶段的访问工作集,在缓存够大的情况下,它是可以直接命中缓存的。
上面主要介绍了存储技术和计算机软件一些基本的和持久的属性:
而现在计算机系统中,硬件和软件这些基本属性互相补充的很完美,即高层从底层走,存储设备变得更慢、更便宜和更大,顶层的是CPU寄存器,CPU可以在一个时钟周期内访问他们,接下来是高速缓存SRAM、主存等 。
看上图所示,其中心思想就是:对于每个k,位于k层的更快更小的存储设备是作为位于k+1层更大更慢设备的缓存。
概括来说,基于缓存的存储器层次结构行之有效,因为较慢的存储设备比较快的设备更便宜,还因为程序倾向于展示局部性。
今天,这篇文章主要学习了计算机存储器的相关知识。
阅读更多内容,请浏览我的个人小站: 爱上编程
原文:https://www.cnblogs.com/pekxxoo/p/csapp-6.html