随便讲讲“交叉存储技术”

Posted: 2011/04/29 in 计算机学习
标签:, ,

  我们知道,主存储器,也就是大多数人平时所说的“内存”,是现代计算机中必不可少的组成部分,用以存放操作系统和程序运行时所需的各种临时数据(当然,更详细地讲,这里所说的“临时数据”,其实是指指令及其所需的操作数)。平时,当我们破财去购买内存条时,那上面通常会标明这根内存条的最大容量;就以本人这台烂机为例,机箱内插着一根512M大小和另一根1024M大小的内存条(台湾人好像叫这个是“记忆体”,未详考),也就是说,本人这台老机总共可用的内存差不多是1.5G。很多人会以为,一根内存条就是一根内存条,它本身就是最小单元,但是,事实上,我们忽略了一个很重要的细节,那就是,存储器本身是由多块被称作是“随机访问存储器(RAM)”的芯片构成的,每块芯片都有固定大小的容量,但通常都不会太大;所以,本人那根512M的内存条极有可能是由多块RAM芯片所构成的。因此,存储器本身不是最小的单元,RAM芯片才是最小的存储单元。
  正如刚才所讲的,许多块RAM芯片“拼接”在一起构成了一根内存条,那么,这些芯片是怎么“拼接”的呢,不会是杂乱无章的吧?当然不会是乱配鸳鸯啦,人家可是很守规则的,很本分的。实际上,每块芯片通常会采用“长度×宽度”的方式来表示大小,而以芯片构成的存储器也是要用这种方式来表示其容量的。比如,2K × 8 的RAM芯片表示它有2K长(具有2K=2×210=211个字)和8位宽(每个字都是8位长的)。如果要用这种芯片去“拼接”出一块32K × 16的内存条的话,那么很显然,只能“拼接”成16行2列的形式:

图一

图一

  这就是“拼接”时所必须遵循的规矩——无论是RAM芯片,还是存储器,都必须是以“长度×宽度”形式表示的阵列。
  不过,这和我们要讲的”交叉存储技术“之间有什么关系么?我们还是以图一中的存储器为例。如果这根内存条插在了一块主板上,而板载CPU可处理16位字,其操作系统也支持16位字,那么,如果机器是按字编址的话,就需要用两个芯片来处理一个字的全部宽度(16位)。这样,对于一块32K × 16的内存条而言,总共需要编址215(32K=25×210=215)个,每个地址需要有15位长;但对于内存条中的”一行“,即两块芯片”拼接“成的一块大小为2K×16的存储区域(我们称为一个存储器模块或存储器组),却只需要编址211个(2K=2×210=211),每个地址需要有11位长。从物理上讲,一块2K×8的RAM芯片在出厂时只有11根地址线,我们不能把它增加到15位以满足我们的编址需要。
  为了解决这种冲突,那些计算机的大牛们就想出了一种折衷的办法:对于前面的问题,倘若CPU得到一个15位长的地址,需要以此从主存储器中获取数据时,CPU会取地址的4位(或是高4位,或是低4位),来确定自己要从哪一“行”,也就是哪一个存储器模块中找数据,然后用剩余的11位来确定自己所需的数据究竟住在这一行中的哪个具体位置(还要强调,在这里,一个存储器模块是2K×16,而不是2K×8,这就是说,我们把两块芯片看成整体,然后把它称作是一个“模块”)。这种方法就是有名的“存储器交叉存储技术”,英文上叫做Memory Interleaving。这种技术将地址分成了两部分,一部分用于寻找存储器模块,另一部分用以找到在该模块中的具体位置。
  但是,我们又有了一个疑问:这两部分究竟该怎么去分?一般来讲,就那么两种分法,一种是“低位交叉存储(Low-order Interleaving)”,还有一种是“高位交叉存储(High-order Interleaving)”。
  高位交叉存储是一种非常简单,非常直观,非常容易理解的编址方法。这种方法要求使用地址的高位来选择存储器组(存储器模块)。对于前面的例子,那就是使用地址的高4位(最左边的4位)来选择一个模块,再用剩余的11位来找到具体的位置。
  我们来给图一中的存储器中的每一行,也就是一个模块编上号,总共需要4位的二进制数来表示,如图二所示。

图二

图二

  这时,如果我们有一个15位的地址 0000 0000 0000 111(十进制6),我们首先取其高4位,即 0000 ,可以以此确定该地址在第1个模块里。然后,剩余的11位标明,数据存放在第1个模块里的第7个位置上(标号从0开始)。

图三

图三

  可以看到,在“高位交叉存储”中,编址是按“从上到下”的顺序来进行的,中间没有任何“跳跃”,严格按照一个模块一个模块的顺序下去,呈现出“线性”的特点。
  同样以图二为依据,并且我们得到的地址仍然是 0000 0000 0000 111,其低4位是 0111,我们可以确定我们要通过该地址寻找的数据就放在第8个模块里;剩余的11位,也即 0000 0000 000 表明,数据住在第8个模块里的第0个位置上。

图四

图四

  可见,同样的地址,如果编址模式不同,CPU找到的位置是不同的,所取到的数据,自然也就很有可能是不同的了。
  我们还遗漏了什么吗?的确,笔者刚刚提到,“低位交叉存储”的一个很显著的特点就是它编址的方式是“跳跃的”而非“线性的”。这是什么意思?正所谓“一图胜千言”,看看下面的图您就明白了:

图五

图五

  这种方式可称作是“轮回式”的编址模式;在一个模块里编上号后,“跳跃”到下一个模块相应的位置上继续编号,如此循环往复,直到编完为止。
  而“高位交叉存储”则简单多了,因为它是顺序、线性的:

图六

图六

额外的讨论:连续地址与连续内存空间

  在我们最初学习C语言的那段噩梦般的时光里,我们常常会听到“连续的地址”、“连续的内存空间”这样的语句,比如,“定义一个数组,编译器就会给它分配一片连续的存储空间”等。以前,我们会毫不犹豫地认为,“连续的地址”就意味着在物理上的一块连续的内存空间,当地址加 1 后,我们仍处在这块物理内存之中。但是现在,一个问号出现在我们的头顶:连续的地址难道真的就是一一映射到一片连续的物理内存空间么?正如我们之前所讲的那样,如果编址模式是“高位交叉存储”的话,那么前面的疑问句就可以成为陈述句。毫无疑问,“高位交叉存储”那“顺序式”的编址模式使得连续的地址等同于连续的内存空间。
  但是,对于“低位交叉存储”,情况就不同了。看看图五,假如编译器给我分配了一定的内存空间,且这些空间的地址分别是0,1,2,3,4。照理说,它们的确是获得了连续的地址,可是很明显,它们并不“住”在一起,它们并不是一块连续的内存空间,而是相互独立且离散的五块空间。因此,“低位交叉存储”就使得地址连续不等同于空间连续。
  另外,如果要向内存写入16个字的话,对以“高位交叉存储”模式来进行编址的情况,这16个字只能占用第一个存储器模块里16个字的大小,而不会对其它模块产生影响;但在“低位交叉存储”时,这十六个字会被分别写入这十六个存储器模块中,且每个模块些一个字。
  “使用低位交叉存储方式并配合相应的总线技术,可以在一个存储器模块的读写操作完成前,就开始另一个存储器模块的读写操作。也就是在存储器模块之间的读写操作可以相互重叠。” Linda Null和Julia Lobur在《计算机组成与体系结构》中这样讲。不过本人才疏学浅,不能完全理解她们的意思,只好留到以后去解决了。

评论
  1. hceasy说道:

    只有这一篇?渴望看到这类的知识。。

    • Justin Yang说道:

      最近琐事太多,没时间写文章,哈,大三就这样……这个只是学习笔记,还有些谬误啦,帮忙看看有什么错误,呵呵

  2. hceasy说道:

    这个我不懂,没法挑刺,抱着学习的态度来的…o∩_∩o

留下评论