JobPlus知识库 IT 软件开发 文章
计算机系统中与存储有关的那些事

最近工作中,经历了很多项目问题的调试,把这些问题归总起来,其中和存储有关的,独占一半。而存储对计算机系统造成的影响又可分为两块:一是系统功能的稳健性;二是程序的执行效率。

 

存储器结构

1.1 存储器层次结构

由于访问速度、成本、功耗等指标的制约,计算机系统中的存储往往不是作为一个单一的大块存在,而是被设置成一个多级的层次结构。作为一个程序员,需要理解存储器层次结构,因为它对应用程序的性能有着巨大的影响。

图1中展示了一个典型 计算机系统的存储层级结构。和金字塔模型很像,越靠近金字塔顶端的存储器,离CPU越近,访问更便利且访问速度快,但同时它们的容量也越来越小;反之越靠近底层,存储容量越大,访问速度却越来越慢。

最高层的L0,是CPU寄存器,CPU可以在一个时钟周期内访问他们;接下来是一个或多个小型到中型的基于SRAM的高速缓存存储器,可以在几个CPU时钟周期内访问它们;然后是一个大的基于DRAM的主存,可以在几十到几百个时钟周期内访问它们;接下来是慢速但容量很大的本地磁盘;最后,甚至有些系统会通过网络访问其远程服务器上的磁盘。

图1 存储器层次结构

 

高速缓存可以存在一级或多级,甚至不存在于一些低性能的单片机中。TI C64X架构中设计有2级的高速缓存,其数据和代码的存取机制在本订阅号之前的文章“TI C6000 数据存储处理与性能优化”中有过描述。

 

1.2 存储器的访问

一个编写良好的计算机程序常常具有良好的局部性(locality)

局部性通常有两种不同的形式:时间局部性和空间局部性。

  • 时间局部性:在一个具有良好时间局部性的程序中,被访问过一次的内存位置很可能在不远的将来再被多次访问 。

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

例如对一个二维数组求和:

for (i=0; i<M; i++)

     for(j=0; j<N; j++)

          sum += data_tab[i][j];

其中,sum在循环迭代中被多次访问,它具有良好的时间局部性,但因其为标量,因此没有空间局部性。对二维数组data_tab而言,其元素在存储中顺序存储,因此有好的空间局部性,但由于其每个元素只访问一次,因此时间局部性很差。

另外,假设把上面第三行替换成:

sum += data_tab[j][i];

由于二维数组是按行依次存储,则每次循环对内存访问的步长由1变为N,空间局部性变差。像这样看上去对程序很小的改动对它的局部性有很大的影响。

 

存储类型

2.1 随机访问存储器(RAM)

上电使用,掉电存储内容丢失。

静态RAM(SRAM):存储单元具有双稳态特性,上电就能保持它的值,对光和电噪声等干扰不敏感。它使用晶体管多,因而密集度低,更贵,功耗更大。

动态RAM(DRAM):对每个位存储为对一个电容的充电,因漏电的原因需要不断刷新来保持存储值。

  • SDRAM(Synchronous DRAM):用与驱动内存控制器相同的外部时钟信号的上升沿,来作为控制信号。

  • DDR SDRAM(Double Data-Rate Synchronous DRAM):通过使用两个时钟沿作为控制信号,从而使DRAM的速度翻倍。它是用提高有效带宽的很小的预缓冲区的大小来划分的,如DDR(2位)、DDR2(4位)、DDR3(8位)。

表1 SRAM与DRAM性能比较

2.2 非易失性存储器

非易失性存储器,即使在关电后仍能保存着它们的信息。由于历史的原因,它们也被整体成称为ROM(Read Only Memory),但很多ROM类型是即可以读也可以写的。

PROM(Programble ROM):只能被编程一次,PROM的每个存储器单元有一种熔丝,只能用高电流熔断一次。

EPROM(Erasable Programble ROM):可擦写可编程,对它的编程是通过一种把1写入EPROM的特殊设备来完成的。

EEPROM(Electrically Erasable Programble ROM):电子可擦除,不需要一个物理上独立的编程设备,因此可以直接在芯片上编程,能被编程的次数可以达到10e5次。

闪存(flash):基于EEPROM的一类非易失性存储器。对它写数据必须先将芯片中对应的内容清空,然后再写入,也就是通常说的“先擦后写 ”。

  • NAND flash:对它的操作以“块 ”为基本单位,因此要修改一个字节,必须重写整个数据块。它的容量大,适合做大量数据的存储。

  • NOR flash:对它的操作以“字 ”为基本单位。它的容量相对较小,成本大,一般用来存储程序。

 

2.3 磁盘

磁盘由盘片构成,它是广为应用的保存大量数据的存储设备。不过从磁盘上读信息的时间为毫秒级,比从DRAM读慢了10万倍,比从SRAM读慢了100万倍。

 

栈和堆

3.1 栈(stack)

栈是一个“后进先出”的存储空间,程序运行中,代码“过程 ”涉及到的返回地址、过程参数、需要保存的寄存器信息都被压入栈中,过程中声明的临时变量也是在栈中开辟存储。

过程的形式多样:函数、方法、子例程、中断处理函数等。当过程需要的存储空间超出寄存器能够存放的大小时,就会在栈上分配空间,这部分空间称为过程的栈帧。

通常,栈底位于高地址,随着数据的压入,栈向低地址方向增长,而栈指针指向栈顶。将栈指针减少一个适当的量,可以为没有指定初始值的数据,在栈上分配空间;类似的,可以通过增加栈指针来释放空间。因为栈的位置取决于.stack段分配在什么地方,所以栈的实际地址是在连接时决定的。

假设过程P调用过程Q时,相关的控制和数据信息添加到栈尾,当Q返回时,这些信息会释放掉。如果存在多级调用(包括递归调用),较早的栈帧也会累积下来,直到它对应的过程结束。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
358人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序