继续
接着上一篇,继续 。
这篇总结陆陆续续写了 2 周 - 3 周,一共 4 千多字
是非审之于己,毁誉听之于人,得失安之于数。
信息存储
大多数计算机使用 8 位的块,或者字节(byte),作为最小的可寻址的内存单位,而不是访问内存中单独的位。机器级程序将内存视为一个非常大的字节数组,称为虚拟内存。内存的每个字节都由一个唯一的数字来标识,称为它的地址,所有可能地址的集合就称为虚拟地址空间。顾名思义,这个虚拟地址空间只是一个展现给机器级程序的概念性映像。实际的实现是将动态随机访问存储器(DRAM)、闪存、磁盘存储器、特殊硬件和操作系统软件结合起来,为程序提供一个看上去统一的字节数组。
程序的机器级表示
计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC C 语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令。然后 GCC 调用汇编器和连接器,根据汇编代码生成可执行的机器代码。
机器级代码
计算机系统使用了多种不同形式的抽象,利用更简单的抽象模型来隐藏实现的细节。对于机器级编程来说,其中两种抽象尤为重要。
第一种是由指令集体系结构或指令集架构(Instruction Set Architecture,ISA),来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式,以及每条指令对状态的影响。大多数 ISA,包括 x86-64,将程序的行为描述成好像每条指令都是按顺序执行的,一条指令结束后,下一条再开始。处理器的硬件远比描述的精细复杂,它们并发地执行许多指令,但是可以采取措施保证整体行为与 ISA 指定的顺序执行的行为完全一致。
第二种抽象是,机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个非常大的字节数组。存储器系统的实际实现是将多个硬件存储器和操作系统软件组合起来。
存储器层次结构
存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。CPU 寄存器保存着最长用的数据。靠近 CPU 的小的、快速的高速缓存存储器作为一部分存储在相对慢速的主存储器中数据和指令的缓冲区域。主存缓存存储在容量较大的、慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域。
为什么要理解存储器层次机构
因为它对应用程序的性能有着巨大的影响。如果程序需要的数据是存储在 CPU 寄存器
中的,那么在指令的执行期间,在 0 个周期内就能访问到它们。如果存储在高速缓存
中,需要 4 ~ 75 个周期。如果存储在主存
中, 需要上百个周期。而如果存储在磁盘
上,需要大约几千万个周期。
计算机系统中一个基本而持久的思想:如果理解系统是如何将数据在存储器层次结构中上上下下移动的,使得它们的数据项存储在层次结构中较高的地方,在那里 CPU 能更快地访问到它们。
这个思想围绕着计算机程序的一个称为局部性
的基本属性。具有良好局部性的程序倾向于一次又一次地访问相同的数据项集合,或是倾向于访问邻近的数据项集合。具有良好局部性的程序比局部性差的程序更多地倾向于存储器层次结构中较高层次处访问数据项,因此运行的更快。
基本的储存数据:
- SRAM 存储器
- DRAM 存储器
- ROM 存储器
- 旋转的和固态的硬盘
随机访问存储器
随机访问存储器(RAM)分为两类:静态的和动态的。静态的 RAM(SRAM)
比动态RAM(DRAM)
更快,但也更贵。SRAM
用来作为高速缓存存储器,既可以在 CPU 芯片上,也可以在片下。DRAM
用来作为主存以及图形系统的帧缓冲区。
静态 RAM
SRAM 将每个存储在一个双稳态
的存储器单元里。每个单元是用一个六晶体管电路来实现的。SRAM 存储器单元的双稳态特性,只要有电,它就会永远地保持它的值。即使有干扰(例如 电子噪音)来扰乱电压,当干扰消除时,电路就会恢复到稳定值。
动态 RAM
DRAM 将每个位存储为对一个电容的充电。这个电容非常小,通常只有大约 30 微克法拉。DRAM 存储器可以制造得非常密集 – 每个单元由一个电容和一个访问晶体管组成。但是,与 SRAM 不容,DRAM 存储器单元对干扰非常敏感。当电容的电压被扰乱之后,它就永远不会恢复了。暴露在光线下会导致电容电压改变。实际上,数码相机和摄像机中的传感器本质上就是 DRAM 单元的列阵。
总结 SRAM、DRAM
只要有供电,SRAM 就会保持不变。与 DRAM 不同,它不需要刷新。SRAM 的存取比 DRAM 快。SRAM 对诸如光和电噪声这样的干扰不敏感。代价是 SRAM 单元比 DRAM 单元使用更多的晶体管,因而密集度低,而且更贵,功耗更大。
内存模块
DRAM 芯片封装再内存模块中,它插到主板的扩展槽上。Core i7 系统使用的 240 个引脚的双列直插内存模块,它以 64 位为块传送数据到内存控制器和从内存控制器传出数据。
增强的 DRAM
有许多种 DRAM 存储器,而生产商试图跟上迅速增长的处理器速度,市场上就会定期推出新的种类。每种都是基于传统的 DRAM 单元,并进行一些优化,提高访问基本 DRAM 单元的 速度。比如:快页模式、扩展数据输出、同步 DRAM、双倍数据速率同步、视频 RAM 等。
非易失性存储器
如果断电,DRAM 和 SRAM 会丢失它们的信息,从这个意义上说,它们是易失的,另一方面,非易失性存储器即使是在关电后,仍然保存着它们的信息。现在有很多种非易失性储存器。
闪存
闪存是一类非易失性存储器,基于 EEPROM,他已经成为了一种重要的存储技术。闪存无处不在,为大量 的电子设备提供快速而持久的非易失性存储,包括数码相机、手机、音乐播放器、PDA 和笔记本、台式机和服务器计算机系统。现在有一种新型的基于闪存的磁盘驱动器,称为固态硬盘
,它能提供相对传统旋转磁盘的一种更快速、更强健和更低能耗的选择。
访问主存
数据流通过称为总线(bus)的共享电子电路在处理器和 DRAM主存直接来来回回。每次 CPU 和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务
。读事务从主存传送数据到 CPU 。写事务从 CPU 传送数据到主存。
示例计算机系统的配置
主要部件是 CPU 芯片、我们将称为 I/O 桥接器的芯片组(其中包括内存控制器),以及组成主存的 DRAM 内存模块。这些部件由一对总线连接起来,其中一条总线是系统总线
(system bus),它连接 CPU 和 I/O 桥接器,另一条总线是内存总线
(memorry bus),它连接 I/O 桥接器和主存。I/O桥接器将系统总线的电子信号翻译成内存总线的电子信号。正如我们看到的那样,I/O桥也将系统总线和内存总线连接到I/O总线,像磁盘和图形卡这样的I/O设备共享I/O总线。不过现在,我们将注意力集中在内存总线上。
磁盘存储
磁盘是广为应用的保存大量数据的存储设备,存储数据的数量级可以打到几百到几千千兆字节,而基于 RAM 的储存器只能有几百或几千兆字节。不过,从磁盘上读信息的时间为毫秒级,比从 DRAM 读慢了 10 万倍,比从SRAM 读慢了 100 万倍。
磁盘构造
磁盘是由盘片构成的。每个盘片有两面或者称为表面,表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴,它使得盘片以固定的旋转速率旋转,通常是 5400 ~15000 转每分钟。磁盘通常包含一个或者多个这样的盘片,并封装在一个密封的容器内。
磁盘每个表面是由一组称为磁道
的同心圆组成的。每个磁道被划分为一组扇区
。每个扇区包含相等数量的数据位(通常是 512 字节),这些数据编码在扇区上的磁性材料中。扇区之间间隙
分隔开,这些间隙中不存储数据位。间隙存储用来标识扇区的格式化位。
磁盘是由一个或者多个叠放在一起的盘片组成的,它们被封装在一个密封的包装里,整个装置通常被称为旋转磁盘
,以使之区别于基于闪存的固态硬盘 (SSD),SSD 是没有移动部分的。
访问磁盘
CPU 使用一种称为内存映射I/O的技术来向I/O设备发射命令,如下如:
在使用内存映射I/O的系统中,地址空间中有一块地址是为与I/O设备通信保留的。每个这样的地址称为一个I/O端口。当一个设备连接到总线时,它与一个或者多个端口相关联(或它被映射到一个或多个端口)。
设备可以自己执行读或者写总线事务而不需要 CPU 干涉的过程,称为直接内存访问
。这种数据传送称为 DMA 传送
。
固态硬盘
固态硬盘是一种基于闪存的存储技术,在某些情况下是传统旋转磁盘的极有吸引力的替代产品。SSD 封装插到I/O总线上标准硬盘插槽(通常是 USB 或 SATA)中,行为就和其它硬盘一样,处理来自CPU 的读写逻辑磁盘块的请求。一个 SSD 封装由一个或多个闪存芯片
和闪存翻译层
组成,闪存芯片替代传统旋转磁盘中的机械驱动器,而闪存翻译层是一个硬件/固件设备,扮演与磁盘控制器相同的角色,将对逻辑块的请求翻译成对底层物理设备的访问。
存储技术趋势
不同的存储技术有不同的价格和性能折中。SRAM 比 DRAM 快一点,而 DRAM 比磁盘要快很多。另一方面,快速存储总数比慢速存储要贵的。SRAM 没字节的造价比 DRAM 高,DRAM 造价又比磁盘高的多。SSD 位于 DRAM 和旋转磁盘之间。
局部性
一个编写良好的计算机程序常常具有良好的局部性。也就是,它们倾向于引用邻近与其他引用过的数据项的数据项,或者最近引用过的数据项本身。这种倾向性,被称为 局部性原理
,是一个持久的概念,对硬件和软件系统的设计和性能都有着极大的影响。
局部性通常有两种不同的形式:时间局部性
和空间局部性
。在一个具有良好时间局部性的程序中,被引用过一次的内存位置很可能在不远的将来再被多次引用。在一个具有良好空间局部性的程序中,如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置。
一般而言,有良好局部性的程序比局部性差的程序运行得更快
。现代计算机系统的各个层次,从硬件到操作系统、再到应用程序,他们的设计都利用了局部性。在硬件层,局部性原理允许计算机设计者通过引入称为高速缓存存储器
的小而快速的存储器来保存最近被引用的指令和数据项,从而提高对主存的访问速度。在操作系统级,局部性原理允许系统使用主存作为虚拟地址空间最近被引用块的高速缓存。类似的,操作系统用主存来缓存磁盘文件系统中最近被使用的磁盘块。局部性原理在应用程序的设计中也扮演着重要的角色。
局部性小结
- 重复引用相同变量的程序有量良好的时间局部性。
- 对于具有步长为 k 的引用模式的程序,步长越小,空间局部性月哈哈。具有步长为 1 的引用模式的程序有很良好的空间局部性。在内存中以大步长跳来跳去的程序空间局部性会很差。
- 对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。
存储器层次结构
总结
基本存储技术包括随机存储器(RAM)、非易失性存储器(ROM)和磁盘。RAM 有两种基本类型。静态 RAM(SRAM) 快一些,但是也贵一些,它既可以用作 CPU 芯片上的高速缓存,也可以用作芯片下的高速缓存。动态 RAM(DRAM)慢一点,也便宜一些,用作主存和图形帧缓冲区。即使是在关电的时候,ROM 也能保持它们的信息,也可以用来存储固件。旋转磁盘是机械的非易失性存储设备,以每个位很低的成本保存大量的数据,但是其访问时间比 DRAM 长的多。固态硬盘(SSD)基于非易失性的闪存,对某些应用来说,越来越成为旋转磁盘的具有吸引力的替代产品。
一般而言,较快的存储技术每个位会更贵,而且容量更小,这些技术的价格和性能属性正在以显著不同的速度变化着。特别地,DRAM 和磁盘访问时间远远大于 CPU 周期时间。系统通过将存储器组织成存储设备的层次结构来弥补这些差异,在这个层次结构中,较小、较快的设备在顶部,较大、较慢的设备在底部。因为编写良好的程序有好的局部性,大多数数据都可以从较高层得到服务,结果就是存储系统能以较高层的速度运行,但却有较低层的成本和容量。
程序员可以通过编写有良好空间和时间局部性的程序来显著地改进程序的运行时间。利用基于 SRAM 的高速缓存存储器特别重要。主要从高速缓存取数据的程序能比主要从内存取数据的程序运行得快得多。