处理器基础-要点与实例

0. 引言

本文着力解决如下问题:

- 讲体系结构的教材[1],着重于体系结构的理论,没有实例参考;讲实现的教材[2],只有实现细节,没有背后思想。

- 两种教材都没有从应用来,再到应用中去。

- 多数读者需要的是理清楚理念,基于此掌控已有IP,或者进行设计实践和创新,并指导应用。

- 计算机体系结构有着丰富的内容,并且涉及到诸多因素,但是理清楚脉络则纲举目张。

- 理清楚基本结构有助于拓展理解工具链、应用,有助于开发当下针对AI的流处理器。

 

本文脉络:

- 先给出应用和处理器的基本结构。

- 接下来分析应用需求,明确体系结构需要处理的相关问题,并以此探讨体系结构和指令集的思想。

- 以MIPS和ARM为例,实现基本指令集,并初步探讨扩展问题。

- 回归到应用,探讨体系结构如何解决应用问题,以及对于软件编程的启示。

1. 基本应用和处理器结构

1.1 基本处理器结构模型:

注解:

- 典型的处理器由存储、数据路径、控制路径三部分组成

- 存储部分可以进一步扩展为SRAM/Cache/加速器/IO等,代表系统的输入输出

- 处理和运算部分可以扩展处理器功能如特权模式,也可以扩展处理能力如SIMD/VLIW/MIMD/SP

- 系统按照冯诺依曼存储程序计算机理念运行,一般经过取指、译码、执行、写回几个阶段,实际设计和应用会略有不同

1.2 基本应用程序的例子

int * i_mem, i_buf, o_mem, o_buf;

int log2(int i)

{}

interrput 2 exception_handler()

{

}

main()

{

    sys_init();

        while(1)  

        {   // --- init

                 int sum = 0;                

                 // --- input

                 if(i_rdy)

                         i_mem = i_buf;

                 // --- processing

                 for(i=0; i<len; i++)  {

                     sum = sum + i_mem;                       

                 }

                 o_mem = log2(sum)                

                 // --- output

                 if(o_rdy)

                         o_buf = o_mem;  }

}

注解:

- 程序包含系统初始化、主业务流、异常处理三部分

- 主业务流按照输入-处理-输出的流程运转

- 处理部分针对一定数据类型(不同长度、有无符号、精度,可以在指令及操作码中体现,也可以加硬件标记?)进行处理(算数、逻辑、移位),对应处理器结构模型的ALU部分。实际的应用任务经过便一起处理形成指令,处理不能直接支持的指令如大数运算也会由编译器组合使用指令实现。具体应用很可能扩展如浮点、十进制、字符串、图形操作、超越函数、ARM CLZ/test指令。

- 冯诺依曼计算机按指令逐条进行,同时有循环、分支(循环中也有分支判断),分支会产生指令地址跳转。结构化程序的函数调用是一种特殊的跳转(。中断是另一种特殊的跳转(保存中断前下一条指令地址和相关寄存器状态,以便中断返回)。相关的指令运行由处理器结构模型的控制路径根据数据处理路径的状态实现。具体应用可能会扩展系统调用、自陷等指令。

- 数据与ALU之间的传输通过寄存器实现,寄存器也用于保存计算和处理器运转的状态。一个特殊情况是立即数,其作为指令的一部分传递到数据处理路径,但是受限于指令的长度需要附加额外处理。具体应用可能会扩展虚拟存储管理等指令。

2. 指令集和架构设计的基本问题和处理方法

应用明确之后可以开展指令集和架构设计,基本问题和处理方法可参考文献[2]。

主要问题有两个:存储和寻址,指令集编码

2.1 存储和寻址

按照存储方式,CPU大约可以分成堆栈型(Java虚拟机ByteCode)、累加器型(英特尔处理器和51单片机)、寄存器型(当下多数处理器属于此类)。前者指令长度短,后者代码高效(寄存器比存储器快,而且寻址所需位数较少)。

寄存器型存储方式又分为寄存器-寄存器型、存储器-寄存器型、存储器-存储器型,前者较为普遍,一般都有专门的指令用于数据加载和存储。一般有运算、参数传递、系统专用等几类寄存器。

相应的,寻址方式有立即数、寄存器、直接地址、寄存器间接寻址、偏移寻址(多用于if跳转,跳转目标地址编译器计算并写进机器程序)。其中立即数寻址和偏移寻址使用频率最高,注意立即数大小和偏移量大小都会影响指令;特殊一点的还有寄存寻址的变种如索引寻址、自增自减寻址、缩放寻址。寻址方式越复杂指令效率越高但是志玲越复杂(RIXC VS CISC)。

2.2 指令集设计与编码

一般有CISC和RISC两大类。

前者针对具体应用或者高级语言特性增强指令,指令功能强大、逻辑设计复杂。早期英特尔处理器属于此种体制,但后来的宏观是CISC微观还是编译成多条RISC。

RISC基于80%时间运行的常见指令,设计规整,但是编译难度大。

指令集设计考虑的因素:

- 寻址方式,以及支持的寻址空间和寄存器个数。

- 指令长度

- 容易处理

- 留有冗余,以便后续升级保持部分前向兼容,即许多指令集宣称的多元未饱和。

3. 典型指令集

3.1 MIPS基本指令集[2]

MIPS整数运算为三操作数,对应三类寄存器rsrc/rtmp/rdst。通用寄存器32个,每个操作数都可以用段可以使用5bit选择。实际32个寄存器使用的时候有所分工:

 

指令集编码:

 

注解:

- 一般来看,31:26为操作码,25:0为操作数。长操作数指令如立即数运算、带偏移的加载和跳转用15:0;不同的操作其操作码在31:26体现。非长操作数指令,31:26为0,具体操作码利用了5:0。

- 特别地,lui对立即数左移16位赋值给rtmp;几何ori可以对任意寄存器赋值,实现立即数

微架构:

 

注解:

3.2 ARM v4指令集

寄存器组织:

 

 

注解:

- 16个编号,不同模式下访问互有备份以加速切换,共37个

- 通用寄存器使用遵循ATPCS规则:r0~r4用于函数调用传递参数(内嵌汇编编程要遵守,超过的要使用堆栈故指针编程更有效),r4~r7用于保留中间变量。

- CPSR由数据通路到控制通路,控制运转

指令编码表?

3.3 RISC-V指令集

 

中国指令集?

方法:

统计、时序和周期分析

例子:

大数加法

Printf

循环展开

For/if顺序

增加多寄存器加载指令,MAC指令

按位取反

操作系统对于处理器的支持?

函数参数是大的结构体可以使用指针,

ARM和MIPS都有16/32兼容和切换?

参考

[1] 计算机体系结构,张晨曦

[2] 计算机原理与设计——Verilog HDL版,李亚民

[3] ARM体系结构与编程,杜春雷译

[4] risc-v 指令集手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值