读书笔记,如需转载,请注明做者:Yuloran (t.cn/EGU6c76)git
计算机组成原理简介,主要摘选自唐朔飞编著的《计算机组成原理》第二版。程序员
最初的计算机并无微指令系统。因为 M0、M1 都是实际存在的,为了区分,这里分为微程序机器、传统机器。编程
将高级语言翻译成机器语言的程序叫作翻译程序,翻译程序分为编译程序与解释程序两种类型:缓存
计算机体系结构是对计算机组成的一种抽象性描述,代表计算机应包含哪些部分,如指令集、数据类型、存储器寻址技术、I/O 机理等。不一样厂家的具体实现不尽相同,可是对高级语言的开发者来讲,这些都是透明的,即底层实现不一样不会影响到上层应用。架构
现代计算机可认为由三大部分组成:CPU、I/O 设备及主存储器(Main Memory,MM),以下图所示:并发
为了形象地了解计算机的工做过程,对现代计算机的组成框图进行细化:框架
运算器最少包含 3 个寄存器(现代计算机处理器内部每每设有通用寄存器组,如 ARM Cortex-A8 处理器,有 40 个 32bit 的寄存器(32 个通用寄存器,7 个状态寄存器,1 个程序计数器(PC,Program Counter)))和一个算数逻辑运算单元(ALU)。操作系统
控制器是计算机的神经中枢,由它指挥各部件自动、协调地运行。具体而言:翻译
控制器由程序计数器(Program Counter,PC)、指令寄存器(Instruction Register,IR)和控制单元(CU)组成:设计
主存储器(简称主存或内存)包括存储体M、各类逻辑部件和控制电路等。存储体由许多存储单元组成,每一个存储单元又包含不少存储元件,每一个存储元件能够存储一位二进制代码 0 或 1。可见一个存储单元可存储一串二进制代码,称这串二进制代码为一个存储字,这串二进制代码的位数称为存储字长。存储字长能够是 8 位、16 位、32 位等。一个存储字可表明一个二进制数、一串十六进制字符、两个 ASCII 码或者一条指令。
每一个存储单元都有本身的地址,主存的工做方式就是按照存储单元的地址实现对存储字各位的读写,而 MAR、MDR 则用来实现按地址访问:
固然,要想实现一个完整的读/写操做,CPU还须要给主存发送各类控制信号,如读命令、写命令、地址译码驱动信号等。随着硬件电路的发展,主存都制成大规模集成电路的芯片,而将MAR、MDR 集成在 CPU 芯片中。
早期计算机的存储字长通常与机器的指令字长、数据字长相等,故访问一次主存即可取一条指令或一个数据。随着计算机应用范围的不断扩大,每每要求计算机的指令字长、数据字长是可变的。为了适应指令字长和数据字长的可变性,其长度再也不由存储字长肯定,而由字节的个数来表示。好比 4 字节的指令字长就是 32bit,2 字节的指令字长就是 16bit。至此,指令字长、数据字长和存储字长没必要相等,但都必须是字节的整数倍。
下图为32位架构的ARM存储器组织结构,其基本数据类型有:
机器字长是指计算机进行一次整数运算所能处理的二进制数据的位数(整数运算即定点整数运算)。由于计算机中数的表示有定点数和浮点数之分,定点数又有定点整数和定点小数之分,这里所说的整数运算即定点整数运算。机器字长也就是运算器进行定点数运算的字长,即通用寄存器的位数。
主存字长通常等于机器字长,不等的状况下,通常是主存储器字长小于机器字长。例如机器字长是 32 位,主存储器字长能够是 32 位,也能够是 16 位。
Windows 64 位操做系统是针对 64 位机器字长的 CPU 设计的,目前 64 位架构实现技术主要有 AMD6四、Intel EM64T 等。
主存容量 = 存储单元数 * 存储字长
好比,若 MAR 是 32 位,则存储单元个数为: 2^32 = 4 * 1024 * 1024 * 1024个。若存储字长为 8 位,则存储容量 = 4 * 1024 * 1024 * 1024 * 8 bit,即 4G(4 Gigabyte) 。
单位时间内执行的指令平均条数,单位 MIPS(Million Instruction Per Second)。
同一时刻只能有一个部件向总线发送信息,可是能够有多个部件接受信息,由于总线是各部件共享的。
芯片内部的连线,好比寄存器之间、寄存器与 ALU 之间的连线等。
数据总线:双向传输,其条数称为数据总线宽度。数据总线宽度与机器字长、存储字长有关。好比总线宽度是 8 位,指令字长为 16 位,那么 CPU 取出一条指令,就须要访问两次主存。
地址总线:单向传输,指出数据总线上的源数据或目的数据所在存储单元的地址。地址总线的宽度与存储单元个数有关,好比 32 位的地址总线,可编址按字节寻址的存储单元个数为 2^32 = 4 * 1024 * 1024 * 1024 ,即 4 Gigabyte。
从存储器读一个字的数据时,首先由 CPU 将其地址经 MAR 经过地址总线送至主存,而后向主存发读命令。主存接到读命令后,将对应数据读出后,经数据总线送至 MDR。向存储器写一个字的数据时,CPU 先将目的地址经 MDR 经过地址总线送至主存,并将数据送至 MDR,而后向主存发写命令。主存接到写命令后,即可以将 MDR 中的数据经数据总线写至目的地址:
控制总线:决策总线使用权,用来发出各类控制信号。I/O 设备经过控制总线向 CPU 发出总线请求,CPU 经过控制总线向 I/O 设备发出读写命令。
通讯总线:用于计算机系统之间或计算机系统与其它系统(如控制仪表、移动通信等)之间通讯。
在虚拟存储系统中,程序员的编程地址范围与虚拟存储器的地址空间相对应。例如机器指令地址码是 32 位,那么虚拟存储器的存储单元个数可达 2^32 = 4 * 1024 * 1024 * 1024 个,若存储字长为 8 位,则存储容量为 4 Gegabyte,这可能比主存实际的存储单元个数多得多。这类指令地址码称为虚拟地址或逻辑地址,主存的实际地址称为物理地址。虚拟地址到物理地址的转换由操做系统负责实现,好比 Windows 操做系统经过页目和页表来实现虚拟地址到物理地址的转换。若虚拟地址指向的内容在主存,则可被 CPU 直接使用,不然必须先传到主存,而后才能被 CPU 访问。
阅读《Android源代码情景分析》Binder 进程间通讯系统一章,老罗(罗升阳,原书做者)列举 Google 开发Binder 做为 IPC 框架缘由时说:“与传统的进程间通讯机制相比,Binder 进程间通讯机制在进程间传输数据时,只须要执行一次拷贝操做,所以,它不只提升了效率,并且节省了内存空间”,对“只拷贝一次”有点疑惑:“Pipe 不也是只有一次吗?”(犯二了,实际上是两次)
以 Pipe(无名管道,用于具备亲缘关系的进程间通讯,好比父子进程、兄弟进程)为例,进程 A 向进程 B 发送数据,须要先将进程 A 用户空间中的数据拷贝至管道(在内核空间中),而后进程 B 再从管道中将数据拷贝至本身的用户空间,数据确实拷贝了两次。而 Binder 机制下,因为虚拟进程地址空间(vm_area_struct)和虚拟内核地址空间(vm_struct)都映射到同一块物理内存空间,当 Client 端与 Server 端发送数据时,Client(做为数据发送端)先从本身的进程空间把 IPC 通讯数据 copy_from_user 拷贝到内核空间,而 Server 端(做为数据接收端)与内核共享数据,再也不须要拷贝数据,而是经过内存地址空间的偏移量,便可获悉内存地址,整个过程只发生一次内存拷贝。效率最高的当属共享内存了,无需任何拷贝便可访问,只是须要结合信号量来进行信息同步。
一不当心就钻了牛角尖,为了搞清为何 32位 CPU 最大寻址空间是 4G 和 Linux 每一个进程独占 3G 用户空间的问题,把计算机组成原理又翻出来挑着看了一遍。
写文章仍是挺累的,哪怕只是一篇总结(颈椎彻底扛不住)。不过有第一篇,就会有第二篇。之前看过不少文章,都没有总结记录,时间长了,全忘了。。。
[1] 计算机组成原理 高等教育出版社 2000-7 唐朔飞编著
[2] ARM嵌入式体系结构与接口技术 人民邮电出版社 2013-9 杨胜利 刘洪涛编著
[3] Android源代码情景分析 电子工业出版社 罗升阳编著