CPU是如何执行程序的?
一、图灵机的工作方式
组成
- 字符:代表数据或者程序
- 格子:每个格子可以写入字符
- 纸带:由一个个连续的格子组成,好比内存
- 读写头:读取纸带上任意格子的字符,也可以把字符写入到纸带的格子,读写头有一些部件:
- 存储单元:用于存放数据
- 控制单元:用于识别字符是数据还是指令,以及控制程序的流程等
- 运算单元:用于执行运算指令
工作方式
图灵机的主要功能就是读取纸带格子中的内容, 然后交给控制单元识别是数字还是运算符指令,如果是数字则存入到图灵机状态中,如果是运算符,则通知运算符单元读取状态中的数值进行计算,计算结果最终返回读写头,读写头把结果写入到纸带的格子中。
二、冯诺依曼模型
计算机基本结构
- 中央处理器(CPU):寄存器、控制单元和逻辑运算单元,其中控制单元 负责控制CPU工作,逻辑运算单元负责计算,寄存器主要存储计算时的数据
- 通用寄存器:用来存放需要进行运算的数据
- 程序计数器:存储CPU要执行下一条指令(所在的内存地址)
- 指令寄存器:用来存放程序计数器指向的指令
- 内存:程序和数据都是存储在内存,存储的区域是线性的,数据存储的单位是一个二进制位(bit),即0和1,。最小的存储单位是字节(byte),1字节等于8位
- 输入设备
- 输出设备
- 总线
- 地址总线:用于指定CPU将要操作的内存地址
- 数据总线:用于 读写内存的数据
- 控制总线:用于发送和接受信号,比如中断、设备复位等信号
- CPU读写内存数据时,需要经过两个总线
- 先通过地址总线指定内存的地址
- 再通过数据总线来传输数据
三、线路位宽和CPU位宽
数据通过操作电压进行线路传输,低电压表示0,高电压表示1。
- 线路位宽:地址总线的数量,因为一条线路代表一位。
- CPU位宽:CPU的位宽最好不要小于线路位宽,工作起来复杂且麻烦。所以32位的CPU最好和32位宽的线路搭配,因为32位的CPU一次性最多只能操作32位宽的地址总线和数据总线32位的CPU计算两个64位数字的求和结果,需要进行切分成两个高位的32位和两个低位的32位进行计算,因此32位CPU并不能一次性计算出两个64位数字求和结果。
如果计算的数额不超过 32 位数字的情况下,32 位和 64 位 CPU 之间没什么区别的,只有当计算超过 32 位数字的情 况下,64 位的优势才能体现出来。
四、程序执行的基本过程
CPU执行程序的过程
- 第⼀步,CPU 读取「程序计数器」的值,这个值是指令的内存地址,然后 CPU 的「控制单元」操作 「地址总线」指定需要访问的内存地址,接着通知内存设备准备数据,数据准备好后通过「数据总 线」将指令数据传给 CPU,CPU 收到内存传来的数据后,将这个指令数据存⼊到「指令寄存器」。
- 第⼆步,CPU 分析「指令寄存器」中的指令,确定指令的类型和参数,如果是计算类型的指令,就把 指令交给「逻辑运算单元」运算;如果是存储类型的指令,则交由「控制单元」执⾏;
- 第三步,CPU 执⾏完指令后,「程序计数器」的值⾃增,表示指向下⼀条指令。这个⾃增的⼤⼩,由 CPU 的位宽决定,⽐如 32 位的 CPU,指令是 4 个字节,需要 4 个内存地址存放,因此「程序计数 器」的值会⾃增 4;
五、指令
机器内部指令类型
- R指令:⽤在算术和逻辑操作,⾥⾯由读取和写⼊数据的寄存器地址。如果是逻辑位移操作,后⾯还有位移操作的「位移量」,⽽最后的「功能码」则是再前⾯的操作码不够的时候,扩展操作码来表示 对应的具体指令的
- I指令:⽤在数据传输、条件分⽀等。这个类型的指令,就没有了位移量和操作码,也没有了第三个 寄存器,⽽是把这三部分直接合并成了⼀个地址值或⼀个常数
- J 指令:⽤在跳转,⾼ 6 位之外的 26 位都是⼀个跳转后的地址
指令的4个阶段(4级流水线)
- 取得指令(Fetch):CPU 通过程序计数器读取对应内存地址的指令
- 指令译码(Decode):CPU 对指令进⾏解码
- 执⾏指令( Execution):CPU 执⾏指令
- 数据回写(Store): CPU 将计算结果存回寄存器或者将寄存器的值存⼊内存
上面的4个阶段,我们称为指令周期,CPU的工作就是一个周期接着一个周期,周而复始
指令类型(功能划分)
- 数据传输类型:store/load
- 运算类型:加减乘除
- 跳转类型:if-else,switch-case
- 信号类型:中断指令trap
- 闲置类型:nop,执行后CPU会空转一个周期
指令的执行速度
- 1GHz的cpu,代表1秒钟会产生1G次数的脉冲信号,每一次脉冲信号高低电平的转换就是一个周期,称为时钟周期
- CPU在一个时钟周期内,只能完成一个最基本的动作。也就是说时钟频率越高,时钟周期就越短,工作速度也就越快。
- 一个时钟周期内不一定能执行完一条指令,通常需要若干个时钟周期。
- 程序执行的时候,耗费的CPU时间少就说明程序是快的。对于程序的CPU执行时间,我们可以拆解成CPU时钟周期数和时钟周期时间的乘积。
- 程序的CPU执行时间=CPU时钟周期数X时钟周期时间
- 时钟周期时间就是CPU主频
- 时钟周期数=指令数x每条指令的平均时钟周期数
- 所以程序的CPU执行时间=指令数xCPIx时钟周期时间
- 所以想要程序跑得快,只需优化这三者
- 指令数:表示执行程序所需要多少指令以及哪些指令。
- 每条指令的平均时钟周期数CPI:表示一条指令需要多少个时钟周期数
- 时钟周期时间:表示计算机主频,取决于计算机硬件
硬件的 64 位和 32 位指的是 CPU 的位宽,软件的 64 位和 32 位指的是指令的位宽