【001】计算机体系结构
在深入C代码时,我往往更关注于复杂的算法和数据结构,在计算机系统上的注意力大大减少。尤其是随着对嵌入式系统开发的深入,知晓对系统结构的理解尤为重要,更让我理解大学课程结构设计的良苦用心
Concepts
冯祖师爷在First Draft of a Report on the EDVAC描述他心目中计算机的样子:
处理单元(processing unit):包含算术逻辑单元(Arithmetic Logic Unit,ALU)和处理器寄存器(Processor Register),用来完成各种算术和逻辑运算
控制单元(control unit):包含指令寄存器(Instruction Reigster)和程序计数器(Program Counter),用来控制程序的流程
存储器(Memory):存储数据(Data)和指令(Instruction)
大容量外部存储(External mass storage):通常就是硬盘
I/O机制(Input and output mechanisms):我们最常见的,键盘鼠标等等;云服务器通过网络输入输出,所以网卡扮演者I/O的角色
其有以下几个明显特征:
There is no real difference between data and instructions(数据和指令之间没有本质区别)
Data has no inherent meaning
Data and instructions share the same memory
Memory is a linear (one-dimensional) array of storage locations(内存是存储单元的一维空间线性排列)
反观哈佛体系结构其指令与数据存储在不同的内存空间,其可以同时取指令和数据(对于单核处理器来说)。
在现在计算机体系中,这两种架构往往同时存在,各取所长。比如CPU的缓存机制(指令缓存和数据缓存)采用哈佛结构提高访问效率,而整体继续使用冯诺依曼结构来平衡功耗和成本。
CPU
随着发展,处理单元和控制单元集成在了一起,组成了耳熟能详的CPU。CPU是计算机核心部件,是一个能够以顺序指令(opcodes or machine code)指定的方式对数据进行操作的电子器件。指令执行顺序可随应用程序改变,即所谓的程序。不同处理器有不同的指令集(instruction set),不同指令的功能也是不同的。而单个处理器是不可能完成任何任务的,还需要一些外设。
这里对几个概念简单进行区分,因为经常会碰到:
⭐微处理器:单独集成电路上实现的处理器。
⭐微控制器(51系列、AVR):集成电路中包含一个处理器、存储器以及I/O设备。
⭐片上系统(SOC):与微控制器相似,具有一套不同的I/O系统,可针对应用对很多外部存储器提供支持,比如由于手机尺寸的原因,手机制造商们选择把 CPU、内存、网络通信,乃至摄像头芯片,都封装到一个芯片,然后再嵌入到手机主板上。
总线
处理器与计算机体系其他部件交互离不开总线技术,所谓总线,就是具有相关功能的信号线的物理集合。目前大多数微处理器采用三总线结构,数据总线、地址总线、控制总线。
存储器
👽SRAM
下图是TMS320C6678 DSP芯片结构图,距离CPU最近的存储器为L1 Cache,分为指令Cache和数据Cache,仅有32KB大小,反观L2 Cache大小为512KB。正如图中所示,L1 Cache距CPU物理距离最近,所以访问更快。这里通过将指令和数据分开,其实就是来自于哈佛架构,CPU可同时取指令和数据,效率大大提高。
CPU Cache用的是SRAM(static RAM)的存储器,其使用一对逻辑门来保存数据的每一位,是RAM里面最为快速的一种存储器,外围电路简单,功耗低。在 SRAM 里面,一个比特的数据,需要 6~8 个晶体管。所以 SRAM 的存储密度不高。同样的物理空间下,能够存储的数据有限。
☠️DRAM(dynamic RAM)
内存使用DRAM存储器,它使用电容器阵列来保存数据的每一位,因此需要不断地刷新,也会延迟处理器访问的时间。但是,DRAM仅需一个电容和晶体管就可以保存一位,存储密度大,与SRAM相同物理空间下,能存储更多数据。
😹ROM(Read-Only Memory)
ROM是非易失性存储器,标准ROM有大量二极管阵列装配,ROM中未写入的位状态均为1,每一个字节单元都读作0xFF。
烧录:通过向适当的二极管注入一个足够大的电流将其“烧断”,从而在 指定存储单元建立一个零状态。
😹EPROM
传统一次性可编程ROM适合在产品稳定且批量向客户提供,在产品调试时,通常使用EPRAOM可擦写ROM。缺点在于,每次重写必须把芯片从电路上取下来,完成擦除要好几分钟。
😹EEROM
EEROM可以再电路上进行擦除和再编程,叫标准ROM空间小很多,一般应用在断电保存系统参数和模式信息。
👾Flash
也就是闪存,作为最新的ROM技术,同时具备EEPROM可擦除、可编程的特点,也支持大容量存储。Flash按照扇区来组织,擦除重写一个扇区并不会对其他扇区产生影响,在写入一个扇区之前必须先擦除。
I/O系统
除了内存地址,处理器的地址空间也可以是I/O设备。处理器与外设交换数据的方式主要有三种:
📍Programmed I/O, PIO
程序控制处理器完成I/O数据收发
📍Interrupt-driver I/O
外部设备终端处理器,执行终端服务例程
📍Direct Memory Access, DMA
假设你需要从硬盘读取100MB数据存到内存
方式1:处理器每次在硬盘取一个字节到寄存器,然后将寄存器数据保存到内存单元。这样每次传输一个字节,都需要读取指令,解码指令,读取数据,读取下一条指令,解码下一条指令,然后读取下一个数据,如此反复直至所有数据读完。
方式2:用一个叫DMA控制器(DMA Controller,简称 DMAC)设备完成内存和I/O设备之间的告诉数据传输,直接绕开处理器,整个过程无需逐个字节传输,这种方式就是DMA。
🙊著名的kafka项目就是基于DMA实现了数据“零拷贝”,大大提高系统实时性能。
中断
当外部I/O设备需要服务时,处理器该怎么知道呢?如果通过轮训机制,那真的太浪费时间了。中断技术正是解决这一问题,它是一种转移处理器当前程序执行点,以便处理器能够处理已经发生的某些事件的技术。
当一个中断产生时,处理器把寄存器和程序计数器等压入堆栈,保存当前执行状态。接着把中断向量载入程序计数器,其中,中断向量即中断服务例程地址。执行完中断例程,处理器从堆栈中恢复原有的执行状态。
硬件中断中通常使用三种方式判断一个I/O设备中断状态:
轮训:处理器不断检查I/O设备状态
非向量中断:CPU 接收到中断信号后,通常需要通过轮询或查询机制来确定哪个设备发出了中断,然后执行相应的中断服务例程。
向量中断:中断信号中携带一个唯一的向量号,CPU 可以直接通过该向量号找到对应的中断处理程序。
显然,采用向量中断方式可大大提高系统的执行效率。
📌补充
CISC(Complex Instruction Set Computer)/RISC(Reduced Instruction Set Computer)
作为处理器两大分支,CISC每一条指令需要较多指令周期来完成,这样设计原因也许是在计算机发展初期,存储器价格较为昂贵,减少指令数,进而降低存储空间及指令访问次数。反观,RISC执行每一指令只需很少的指令周期,其背后基本原则是,把硅片的复杂性转移到语言编译器里,硬件部分尽可能地保持简单和快速。采用RISC指令集架构的处理器,具备低功耗的特点,在嵌入式设备中得到广泛的应用,推荐大家去了解一下RISC-V这一开源新兴架构,未来一定是物联网中嵌入式终端的大势所趋。
DSP(Digital Signal Processor, 数字信号处理器)
"A embedded system should be designed to achieve its objective in as simple and straightforward a manner as possible. -- John Catsoulis"