第六章 存储器层次结构

存储器层次结构

6.1 存储技术
6.2 局部性
6.3 存储器层次结构
6.4 高速缓存存储器
6.5 编写高速缓存友好的代码
6.7 小结
6.8 关于磁盘的补充讲解

       好的程序代码不仅要有好的算法,对计算机硬件的充分利用也是很关键的一步。

       存储器系统(memorysystem)是一个具有不同容量、成本和访问时间的存储设备的层次结构。CPU寄存器保存着最常用的数据。靠近CPU的小的、快速的高速缓存存储器(cache memory)作为一部分存储在相对慢速的主存储器(mainmemory,简称主存)中的数据和指令的缓冲区域。主存暂时存放存储在容量较大的、慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域。

       一般来说,如果你的程序需要的数据是存储在CPU寄存器中的,那么在指令的执行期间,在零个周期内就能访问到它们。

       如果存储在高速缓存中,需要1〜30个周期。

       如果存储在主存中,需要50〜200个周期。

       而如果存储在磁盘上,需要大约几千万个周期

6.1存储技术

6.1.1 随机访问存储器

       随机访问存储器(Random-AccessMem)分为两类:静态的和动态的。

静态RAM (SRAM) 比动态RAM(DRAM)更快,但也贵得多。SRAM用来作为高速缓存存储器,既可以在CPU芯片上,也可以在片下。

静态存储器

       SRAM将每个位存储在一个双稳态的(bitable)存储器单元里。每个单元是用一个六晶体管电路来实现的。

动态RAM

       DRAM将每个位存储为对一个电容的充电。这个电容非常小,通常只有大约30毫微微法拉 (femtofarad)——30*10^15法拉。不过,回想一下法拉是一个非常大的计量单位。DRAM存储 器可以制造得非常密集——每个单元由一个电容和一个访问晶体管组成。


非易失性存储器

       如果断电,DRAM和SRAM会丢失它们的信息,从这个意义上说,它们是易失的(volatile)。另一方面,非易失性存储器(nonvolatilememory)即使是在关电后,也仍然保存着它们的信息。

       PROM (Programmable ROM,可编程ROM)只能被编程一次。PROM的每个存储器单元有一种熔丝(fUse),它只能用高电流熔断一次。可擦写可编程ROM (Erasable Programmable ROM, EPROM)有一个透明的石英窗口,允许 光到达存储单元。EPROM能够被擦除和重编程的次数的数量级可 以达到 1000 次。电子可擦除 PROM (Electrically Erasable PROM, EEPROM)类似于 EPROM,但是它不需要一个物理上独立的编程设备,因此可以直接在印制电路卡上编程。EEPROM能够 被编程的次数的数量级可以达到105次。闪存(flash memory)是一类非易失性存储器,基于EEPROM,它已经成为了一种重要的存储技术。

访问主存

        数据流通过称为总线(bus)的共享电子电路在处理器和DRAM主存之间来来回回。

       每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务(bustransaction)0 

       读事务(read transaction)从主存传送数据到 CPU。

       写事务(write transaction)从CPU传送数据到主存。


IO桥是将系统总线的电子信号翻译成存储器总线的电子信号。


6.1.2 磁盘存储

       磁盘是由盘片(platter)构成的。每个盘片有两面或者称为表面(surface),表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴(spindle),它使得盘片以固定的旋转速率 (rotational rate)旋转,通常是 5400〜15000 转每分钟(Revolution Per Minute, RPM)0磁盘通常包含一个或多个这样的盘片,并封装在一个密封的容器内。

      一个典型的磁盘表面的结构。每个表面是由一组称为磁道(track)的同心圆组成的。每个磁道被划分为一组扇区(sector)。每个扇区包含相等数量的数据位(通常是512字 节),这些数据编码在扇区上的磁性材料中。扇区之间由一些间隙(gap)分隔开,这些间隙中不存储数据位。间隙存储用来标识扇区的格式化位。


        磁盘有一个或多个叠放在一起的盘片组成,他们被封装在一个密闭的包装里,如上图的(b)所示,整个装置称为磁盘驱动器,我们简称磁盘。SSD(固态硬盘是没有移动的部分的)。

磁盘容量:


磁盘操作:

        盘用读/写头(read/write head)来读写存储在磁性表面的位,而读写头连接到一个传动臂(actuator arm) —端,如图6-10a所示。通过沿着半径轴前后移动这个传动臂,驱动器可以将 读/写头定位在盘面上的任何磁道上。这样的机械运动称为寻道(seek)。一旦读/写头定位到了 期望的磁道上,那么当磁道上的每个位通过它的下面时,读/写头可以感知到这个位的值(读该位),也可以修改这个位的值(写该位)。有多个盘片的磁盘针对每个盘面都有一个独立的读/写头,如图6-10b所示。读/写头垂直排列,一致行动。在任刻,所有的读/写头都位于同一个柱面上。


        磁盘以扇区大小的块来读写数据。对扇区的访问时间(access time)主要有三个部分:寻道时间(seek time)、旋转时间(rotational time)和传送时间(transfer time)。

访问磁盘:


        在磁盘控制器接收到CPU的读命令后,它将逻辑号翻译成一个扇区地址,读该扇区的内容,然后将这些内容直接传送到主存,不需要CPU的干涉,这个过程称为直接存储器传送(Direct Memory Access, DMA),这种数据传送称为DMA传送

6.1.3 固态硬盘

       固态硬盘(Solid State Disk, SSD)是一种基于闪存的存储技术


6.2 局部性

    一个编写良好的计算机程序常常具有良好的局部性(locality)。也就是说,它们倾向于引用 邻近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。这种倾向性,被称为 局部性原理(principle of locality),是一个持久的概念,对硬件和软件系统的设计和性能都有着 极大的影响。

        局部性通常有两种不同的形式:时间局部性(temporal locality)和空间局部性(spatial locality)。

       在一个具有良好时间局部性的程序中,被引用过一次的存储器位置很可能在不远的将来再被多次引用。

       在一个具有良好空间局部性的程序中,如果一个存储器位置被引用了一次,那 么程序很可能在不远的将来引用附近的一个存储器位置。

局部性小结:

        在这一节中,我们介绍了局部性的基本思想,还给出了一些量化评价一个程序中局部性的简单原则

        •重复引用同一个变量的程序有良好的时间局部性。

         •对于具有步长为t的引用模式的程序,步长越小,空间局部性越好。具有步长为1的引用模式(顺序访问一个向量的每个元素)的程序有很好的空间局部性。在存储器中以大步长跳来跳去的程序空间局部性会很差。

         •对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。

例子:

6.3 存储器层次结构


6.3.1 存储器层次结构中的缓存

高速缓存是一个小而快速的存储设备,使用高速缓存的过程称为缓存。

       存储器层次结构的中心思想是:对于每个K,位于K层的更快更小的存储设备作为位于K+1层的更大更慢的存储设备的缓存。

层次结构中的每一层都缓存来自较低一层的数据对象。

数据块总是以块大小为传送单位(transfer unit)在第k层和第k+1层之间来回拷贝


当程序需要第K层的某个数据d时,它首先在K层查找d,如果d存在,就称为缓存命中,否则称为缓存不空中

当发生缓存不命中时,第K层的缓存从第K+1的缓存中取出包含d的块,如果K层的缓存已经满了,可能会覆盖K层中某一个现存的块。

覆盖一个现存的块的过程称为替换或驱逐这个块,被驱逐的块称为牺牲块。


6.4 高速缓存存储器


6.4.1 通用的高速缓存存储器结构

高速缓存的结构可以用元祖(S、E、B、m)来描述。高速缓存的大小(或容量)C指的是所有高速缓存块的大小的总和。标记位和有效位不包括在内。因此C=SXEXB。



3种方式的高速缓存

       直接映射高速缓存(每组一行,即E=1)

       组相联高速缓存

       全相联高速缓存

6.4.2 直接映射高速缓存

        根据E(每个组的高速缓存行数)高速缓存被分为不同的类。每个组只有一行(E=1)的高速缓存称为直接映射高速缓存(direct-mapped cache)。

直接映射高速缓存中的组选择


直接映射高速缓存中的行匹配

       当且仅当设置了有效位,而且高速缓存中的标记与w的地址中的标记相匹配时,这一行包含w的一个拷贝。

直接映射高速缓存中的字选择


直接映射高速缓存的冲突不命中

产生抖动问题:即高速缓存反复加载和驱逐相同的高速缓存块的组(原因,引用的块被映射到同一个高速缓存组),

解决方法:在每个数组的结尾放B字节的填充,例如将原本的float x[8]定义成 float x[12],即消除了抖动不命中。

为什么用中间的位来作为索引


6.4.3 组相联高速缓存

        组相联高速缓存(setassociative cache)放松了在直接映射高速缓存中E=1的限制,所以每个组都可以保存有多于一个的高速缓冲行。一个1<E<C/B的高速缓冲行称为E路相联高速缓冲。


上图是一个2路组相联高速缓冲行的特例…….

6.4.4 全相联高速缓存

       一个全相联高速缓存(fullyassociative cache)是由一个包含所有高速缓存行的组(即E=C/B)组成的。

全相联高速缓存中的组选择


6.4.5 有关写的问题

      读: 高速缓存关于读的操作非常简单,首先,在高速缓存中查找所需字w的拷贝。如果命中,则立即返回给CPU。如果不命中,则从存储器结构中较低层中取出包含字w的块,将这个块存储到某个行中(可能会驱逐一个有效行),然后返回字w。

       写:假设我们要写一个已经缓存了的字w写命中(write hit)。在高速 缓存更新了它的w的拷贝之后,怎么更新w在层次结构中紧接着低一层中的拷贝昵?

1、直写(write-through),就是立即将w的高速缓存块写回到紧接着的低一层中。虽然 简单,但是直写的缺点是每次写都会引起总线流量。

2、写回(write-back),尽可 能地推迟存储器更新,只有当替换算法要驱逐更新过的块时,才把它写到紧接着的低一层中。由于局部性,写回能显著地减少总线流量,但是它的缺点是增加了复杂性。高速缓存必须为每个高 速缓存行维护一个额外的修改位(dirtybit),表明这个髙速缓存块是否被修改过。

        另一个问题是如何处理写不命中。

1、写分配(write-allocate),加载相应的低一 层中的块到高速缓存中,然后更新这个高速缓存块。写分配试图利用写的空间局部性,但是缺点是每次不命中都会导致一个块从低一层传送到高速缓存。

2、非写分配(not-write-allocate),避开高速缓存,直接把这个字写到低一层中。

直写高速缓存通常是非写分配的。写回高速缓存通常是写分配的。

        一般而言,高速缓存越往下层,越可能采用写回而不是直写。

6.4.6 一个真实的高速缓存层次结构的解析

        实际上,高速缓存既可以保存数据也可以保存指令。只保存指令的高速缓存称为i-cache,只保存程序数据的高速缓存称为d-cache。记保存数据又保存指令的高速缓存称为统一的高速缓存(unified cache)。


6.5  编写高速缓存友好的代码

    一般高速缓存友好的基本方法:

    1让常见的情况运行的快。程序通常把大部分时间都花在少量的核心函数上,而这些函数通常把时间都花在了少量循环上。所以集中注意力在核心函数的少量循环上,而忽略其他部分。

    2在每一个循环内部缓存不命中的数量最小。


6.6 综合:高速缓存对程序性能的影响

        理解存储器层次结构本质的程序员能够利用这些知识编写出更有效的程序,无论具体的存储系统结构是怎样的。特别地,我们推荐下列技术:

        ·将你的注意力集中在内循环上,大部分计算和存储器访问都发生在这里。

        ·通过按照数据对象存储在存储器中的顺序、以步长为1的来读数据,从而使得你程序中的 空间局部性最大。

        ·一旦从存储器中读入了一个数据对象,就尽可能多地使用它,从而使得程序中的时间局部 性最大。


6.7 小结

         基本存储技术包括随机存储器(RAM)、非易失性存储器(ROM)和磁盘。RAM有两种基 本类型。静态RAM (SRAM)快一些,但是也贵一些,它既可以用做CPU芯片上的高速缓存, 也可以用做芯片下的高速缓存。动态RAM (DRAM)慢一些,也便宜一些,用做主存和图形帧缓冲区。非易失性存储器,也称为只读存储器(ROM),即使是在关电的时候,也能保持它们的 信息,它们用来存储固件。旋转磁盘是机械的非易失性存储设备,以每个位很低的成本保存大量的数据,但是访问时间比DRAM更长。固态硬盘(SSD)基于非易失性的闪存,越来越变成旋转磁盘对某些应用的具有吸引力的替代产品。

        一般而言,较快的存储技术每个位的价格会更高,而且容量较小。这些技术的价格和性能属性正在以显著不同的速度变化着。特别地,DRAM和磁盘访问时间远远大于CPU周期时间。 系统通过将存储器组织成存储设备的层次结构来弥补这些差异,在这个层次结构中,较小、较 快的设备在顶部,较大、较慢的设备在底部。因为编写良好的程序有好的局部性,大多数数据都可以从较高层得到服务,结果就是存储系统能以较高层的速度运行,但却有较低层的成本和 容量。

        程序员可以通过编写有良好空间和时间局部性的程序来显著地改进程序的运行时间。利用基于SRAM的高速缓存存储器特别重要。主要从高速缓存取数据的程序能比主要从存储器取数据的程序运行得快得多

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值