了解内存的性能特性, 数据局部性, 以及高速缓存操作可以让你设计的软件运行得尽可能地块。
编写卓越代码,需要对计算机体系结构有深刻的了解

冯若依曼结构: CPU, 内存, IO
CPU
在80x86中,CPU是所有动作发生的场所,所有计算都发生在CPU内部。
内存
数据和机器指令存储在内存中, CPU需要时,系统就会将数据 传输给CPU。
IO
所有IO设备都像是内存,但是它们通常位于外部


基本组成部分介绍
总线
有地址总线, 数据总线和控制总线。 总线是一组信号线的集合

数据总线
CPU使用数据总线在计算机系统的各个组成部分之间交换数据。  它的宽度随CPU而不同, 总线宽度是定义处理器“大小”的主要属性之一

决定处理器大小: 处理器数据线根数与最大的通用整数寄存器大小这二者之间,比较小的一个决定处理器大小。

数据总线越大, 访问内存就越快, 而且一次内存操作可以访问更大块的数据。 如 8位、16位、32位及64位数据总线  能够访问8位、16位或者32位 64位大小的内存单元
  
地址总线: 
数据总线 它是CPU与内存位置或者是IO设备之间通信信息的桥梁
但是问题: 它到底和哪块位置的内存或哪个IO设备进行通讯

那么这就需要地址总线。  系统设计者为它们分配了一个唯一的内存地址。   
每当软件访问某个地址时,会通过地址总线传递代表该地址的信号

地址总线的位数决定了可以寻址的内存与I/O位置的最大个数

控制总线
控制总线是电气信号的集合, 它控制处理器如何与系统其它部分通信。 
还是从数据总线出发, CPU使用数据总线在它自身和内存之间传输数据, 系统如何知道是发送还是接收数据

虽然处理器各异,但是有些控制总线是所有处理器上都有的, 包括 系统时钟信号线,中断信号线, 字节使能信号线以及状态信号线。

在某些支持可字节寻址内存CPU的控制总线上会有字节使能信号线。  这些控制线允许16位,32位和64位处理器处理更小块的数据,它可以用来通知对应数据的大小。


80x86系列处理器的控制总线上还有一条信号线用于区分地址空间。 与很多其他处理器不同 x86处理器将内存和IO分成两个独立的空间。
内存和IO享用一条地址总线, 一条额外的控制线用来区分地址时给内存的还是I/O的, 当该信号被激活时,I/O设备使用地址总线低端16位作为地址,而当该信号线为非激活状态时,I/O设备忽略地址总线上的信号线, 而由内存子系统来接管地址总线

内存的物理组织
32位CPU最大寻址为  2的32次方个不同的内存位置。 那么什么是内存位置呢?

前面说过,80x86支持可字节寻址内存,因此,它可以访问更小的内存的内存单元。  内存的最基本的内存单元是 字节。
即  包含20, 24, 32, 或者36条地址线的地址总线, 80x86系列处理器可以寻址  1MB, 16MB, 4GB, 或者 64GB内存


目前,支持内存是可字节寻址的软件很多(所有c/c++程序)
连那些硬件不支持可字节寻址内存的CPU也使用字节地址,并用软件来模拟字节寻址

可以把内存想象为一个字节数组, 第一个字节为零,最后一个字节为 2的n次方减1, 放数据时, 是单个字节单个字节传递的, 数据线上一个字节对应一个地址线上一个地址

如果是传送字或者双字, 就分发一个地址。
比如就传送字来说,  第一个字节的数据放到该地址上, 第二个字节的数据放到下个相邻的地址上。实际上 程序并不知道第二个字节的地址,只是通过第一个字节的地址来一次获得两个字节的数据,这就是输入流中输入汉字, 而在输出流中直接能打出汉字的原因(当然,还有一部分原因是字符编码)。

位地址总线
由于CPU一次访问一个字节,即8位,  所以8位的处理器是最合理的结构
这种可字节寻址意味着意味着,当某个数据小于8位时, 该字节可能会空余出某些位
而且, 可字节寻址并不意味着CPU可以访问从任意位边界开始的八个位。 当你指定内存地址125时, 你得到的是以该地址开始的整整8位

虽然8为数据总线的CPU能够很方便的操作字节值, 它们也可以处理字或双字, 但是 可能要多几次操作。 为了能够一次性调入一个字, 需要引入16位数据线,而对于双字,就是32位


16位处理器: 
    16位处理器能够一次访问一个字, 它将内存组织为2个列: 一个是偶数列,一个是奇数列(简单的说  排序为奇数的地址放在奇数列,偶数的地址放在偶数列)
数据线  的0 到7 即低端字节  连接的是偶数列, 而 8到 15是高端字节 链接时奇数列。  偶数列是与地址总线相连的,即 地址总线访问的内存单元地址永远只是偶数

   由于16位的处理器可以访问任意位置的地址,因此 如果你访问首地址是第125个内存单元, 那么它会由高端字节来发送,但是我们想把它存储在低端字节中,怎么办? 请放心, CPU会自动识别处理好这件事情。
       那么是怎么处理的呢?  即通过两次操作完成,首先读取125的内存地址,在读取126的内存地址, 通过126的内存地址,访问125和126存储的数据 字  然后进行交换。

32位处理器
那是把内存地址分为了4部分, 只有其中的一部分与地址总线相连, 因此地址总线上的地址永远只是4的倍数。 而它如果想一次处理双字,只能是首地址在4的整数倍的地址上。其它情况(3种情况)都需要进行多次操作。  而它对于单字的处理, 遇到高端低端需要交换字节的情况,是16的一半,即只有首地址除4余3的时候。

了解了计算机内部如何存取数据,你就有了使得程序运行更有效率的理论基础

下一次  介绍  64位总线,系统时钟, 和CPU内存访问


Logo

快速构建 Web 应用程序

更多推荐