终于下定决心自己写一个系列来总结一下关于内存的种种知识点。对于内存,很多同学都是持有敬而远之的态度。在上大学的时候没有打牢基础,在平常也不关心内存的使用,反正只要写出的代码能够运行,没有报错就万事大吉了。

包括博主自己对内存也有很多清楚的地方,但是总是抱着得过且过的态度,没有重视那些问题。现在我希望在这系列的博客中能够与大家一起重温一下关于内存的知识,也欢迎大家与我一起留言讨论,一起进步。

1.计算机硬件的五大组成单元

关于计算机硬件的组成,想必大家都不陌生:中央处理器(CPU)的控制单元逻辑运算单元输入单元输出单元以及内存

77b157e3ef42416a85066353c4f04dd4.png

控制单元控制单元是整个CPU的指挥控制中心,由指令寄存器IR(Instruction Register)、指令译码器ID(Instruction Decoder)和操作控制器OC(Operation Controller)等组成,主要用来协调各个组件与各个单元之间的工作。

逻辑运算单元可以执行算术运算(包括加减乘数等基本运算及其附加运算)和逻辑运算(包括移位、逻辑测试或两个值比较)。相对控制单元而言,运算器接受控制单元的命令而进行动作,即运算单元所进行的全部操作都是由控制单元发出的控制信号来指挥的,所以它是执行部件。

输入单元将获得的数据传输给内存,CPU就可以对内存中的数据进行计算或者是判断,经过处理的数据同样被CPU写回内存中,最后数据才从内存传输到输出单元。

以上就是计算机五大组成单元相互协作完成一次数据输入到处理再到输出的大概过程。

从上图中我们可以看到,上述过程中最重要的操作就是CPU与内存之间的数据交互,因此我在这里再将这两个单元之间的交互过程细化一下。

f36d94f59e784a7293d08f41070a4392-CPU2.png

有的同学可能会问到,CPU中不是只有控制单元和逻辑运算单元么?什么时候又多了一个存储单元?这个存储单元又在存储什么数据呢?

其实存储单元包括了缓存和寄存器组,是CPU中暂时存放数据的地方,里面保存着那些等待处理的数据,或已经处理过的数据,通常来说寄存器的大小决定了一次计算可使用的最大数值。CPU访问寄存器所用的时间要比访问内存的时间短。采用寄存器,可以减少CPU访问内存的次数,从而提高了CPU的工作速度。但因为受到芯片面积,集成度和造价所限,寄存器组的容量一般都不大。

2.地址总线,控制总线和数据总线

我们现在已经知道了所有CPU处理的数据都是从内存中读取到的,其实计算机的内存模型很简单,它被设计成了一个由M个连续的字节大小的存储单元组成的数组。每个存储单元都有一个唯一的物理地址(Physical Address, PA)。

既然CPU要从内存中读取数据,那么首先它需要确定的就是存储单元的地址,但是光知道数据存储的位置还是不够的。CPU还需要知道它是要在该存储单元读取还是写入数据,还需要知道它要操作多少字节的数据。

那么CPU是通过什么将地址信息,数据信息和控制信息传送给内存的呢?由于电子计算机能处理和传输的的信息都是电信号,因此计算机中有专门连接CPU和其它芯片的导线,这些导线就是我们常说的总线了。

从物理上来讲总线就是一根根导线的集合;从逻辑上来讲总线可以分为地址总线,控制总线和数据总线。

下图是CPU从3号存储单元读取数据的过程:

329d9c52e8304f5183abbbb62511b0f7-CPU.png

1. 首先CPU通过地址总线将地址信息3发送给内存,告知内存它要找的存储单元是3号存储单元
2. 紧接着CPU在通过控制总线发出读取内存的的命令,告知内存它要做的是读取3号存储单元
3. 最后内存就会将3号存储单元中的数据08通过数据总线发送给CPU,这样CPU就获得了它需要读取的数据了

写操作与上面的读取操作类似:

1. 首先CPU通过地址总线将地址信息3发送给内存,告知内存它要找的存储单元是3号存储单元
2. 紧接着CPU在通过控制总线发出写入内存的的命令,告知内存它要做的是向3号存储单元中写入数据
3. 最后CPU通过数据总线将12发送给内存的3号存储单元

无论是读取还是写入数据,CPU都必须先通过地址总线将它需要找的地址信息发送给存储器,从而找到制定的存储单元。换句话说,地址总线能够传送多少个不同的地址新给存储器,CPU就能够通过地址找到多少个存储单元。

假设我们现在有一个只有10根地址总线的CPU,让我们一起来看一下它最多能传送多少个不同的地址。简单来说,在电子计算机中,导线只有高,低电平的状态之分,换成二进制也就是1或者0。10根总线每根总线可以传送2位的二进制数据,10根总线总共可以传送出2^10 = 1024个地址信息,当每根导线都是低电平状态(表示为0),地址总线传递的地址就是0(最小地址);当每根导线都是高电平状态(表示为1),地址总线传递的地址就是1023(最大地址29+ 28 + 27+ 26 + … + 21 + 20 = 1023)。

下图展示了一个只有10根地址总线的CPU向内存发出11(二进制1011),这10根地址总线上传递的二进制信息。

CPU%E5%9C%B0%E5%9D%80%E6%80%BB%E7%BA%BF%E4%B8%BA10.png

一个CPU有N根地址总线,则可以说这个CPU的地址总线宽度为N。这样的CPU最多可以寻找2n个内存单元。正因为地址总线的宽度决定了CPU最大的可寻址的地址空间,比如32位的地址总线可以表示232个内存位置,每个内存位置存储1byte(字节的数据),所以32位的地址总线最多只能有(232byte = 430byte = 420KB = 410MB = 4GB的内存空间)。

讲完了地址总线之后,我们再来看数据总线。由于CPU与内存或其它器件之间的数据传输是通过数据总线来进行的,因此数据总线的宽度决定了CPU和外界的数据传输速度,比如8根数据总线一次可以传递8位二进制数据(一个字节);32根数据总线一次可以传递4个字节的数据。

还记得我们之前讲到的寄存器么,从内存中读取的尚未处理的或是一些数据计算的中间结果都存在这里。通常来说,数据总线的宽度与寄存器的位数都是相同的,因为寄存器要存储数据总线传来的数据,如果宽度位32的数据总线一次传递了4字节的数据给寄存器,但是寄存器位数不够32位,岂不是还需要额外操作去存储传来的数据么。因此,为了有更好的数据传输的效率,寄存器的位数通常都等于数据总线的宽度。

这里在和大家说一个小知识,我们平常里说的32位CPU或者是64位CPU,指的就是32位的寄存器或是64位的寄存器,也通常等于数据总线的宽度,它与指令集的位数是有联系,但是并不等于地址总线的宽度。比如Intel 8086 CPU 是16位,其指令集也是16位;Intel 80386DX CPU 是32位,其指令集也是32位,但它也保持原16位指令集,这是为了向上兼容。而操作系统的位数是指其所依赖的指令集的位数,因此操作系统的位数可以与CPU的位数相同,如64位的CPU运行着64位的操作系统(支持64位的指令集);但也可以不相同;比如64位的CPU运行着32位的操作系统(支持32位的指令集)。

讲了这么多,同学们也该休息一下了。总结一下本章的博客:

  • 计算机的五大组成单元是:中央处理器(CPU)的控制单元逻辑运算单元输入单元输出单元以及内存
  • 其中CPU要处理的数据必须从内存中获得
  • 地址总线用来传输存储器中存储单元的地址,它的宽度决定了计算机的最大寻址范围,也决定了计算机能支持的最大内存空间
  • 数据总线用来在CPU与存储器之间传递数据,它的宽度决定了每次传递数据的大小
  • 寄存器的位数大小决定了CPU逻辑运算单元一次计算可使用的最大数值,它通常等于数据总线的宽度,也是我们平常所说的多少位CPU的数值。
  • 指令集的位数大小决定了操作系统的位数,也就是我们平常说的多少位的操作系统。

希望我的博客能够帮助基础不那么牢固的同学扫清些障碍,那么我们下节博客再见喽。

参考:
1. http://www.ibm.com/developerworks/library/j-nativememory-linux/
2. 《汇编语言》
3. 《深入理解计算机系统》

总结不易,转载请注明:

转:http://www.wxueyuan.com/blog/articles/2017/11/02/1509629291450.html
文章来源:Jesmin的个人博客