重学操作系统(二)

重学操作系统(二)

前言

这一篇文章准备记录下关于32位和64位相关的知识点。32位和64位我们都熟悉,但是大部分人,包括我,都没有真正去研究过,今天借着拉钩教育这个教程,趁机学习并且总结下,留作以后回顾。

贯穿全文的思考:相比32位,64位的优势是什么?

图灵机的两大贡献

  1. 定义了计算机的计算边界,即可计算理论
  2. 定义了计算机的组成,和程序如何执行

图灵机的构造

图灵机的构造

图片来源于参考中的链接

可以看出,图灵机是很长的白色纸带(模仿内存)和读写头以及一些其它元件(储存元件,控制单元等)组成,这样图灵机就能模仿内存的读写了。

例如:计算11 + 15

  1. 我们先把11,15,+分别写入纸带的三个格子,假定图灵机能识别数字和计算符号。
  2. 图灵机将11和15读入控制单元,控制单元将数字存储到存储单元中。
  3. 遇到加号,读写头将加号传输给控制单元,控制单元识别出加号是预设运算符,因此不放入存储单元,而是传输给运算单元,之后运算单元在存储单元取出11和15,进行运算,将结果存入存储单元,运算单元同时将结果返回给控制单元。
  4. 控制单元将结果返回给读写头,读写头写出结果。

一个问题如果能拆解成图灵机的可执行步骤,那么这个问题就是客可运算的。

冯诺伊曼模型

冯诺伊曼模型

图片来源于参考中的链接

冯诺伊曼模型基本遵循了图灵机的设计,主要分成5个部分:输入,输出,内存,CPU和总线,并且约定用二进制存储和计算,是现代计算机的鼻祖。现代计算机,不管多复杂,都遵循这个模型的设计方式。

冯诺伊曼模型 - 内存

程序和数据被存储在一个线性排列的存储区域内,存储单元是二进制(bit),最小单位为字节(8位,byte),每个字节对应一个内存地址。内存地址编号由0开始,依次递增(类似数组那种存储方式 0 - 长度 - 1)。内存是随机存取器,读写任何位置,速度一样。

冯诺伊曼模型 - CPU

冯诺伊曼模型中的CPU相对简单一些,负责控制和计算。CPU可以计算多个字节的数值,以应对较大数值计算。

  1. 32位:CPU能计算4Byte
  2. 64位:CPU能计算8Byte

为什么这么设计CPU?

一个byte范围是0-255,因此CPU需要支持多个byte一起计算。32位的CPU已经能计算到232 - 1(4294967295)。

  • 控制单元和逻辑运算单元

    • 控制单元负责控制CPU工作,逻辑运算单元负责计算。
  • 寄存器

    • 存储将要被计算的数字,寄存器离计算单元和控制单元很近,速度很快。
    • 通用寄存器:可供用户编程,比如用来存加和指令的两个参数。
    • 特殊寄存器:程序指针是一个特殊寄存器,存储了CPU要执行的下一条指令所在的地址。
    • 指令寄存器:下一条指令被内存读入指令寄存器,在指令执行结束前,它都被存在指令寄存器中。
  • 总线

    • 用于CPU和内存等其它设备通信用的
    • 地址总线:指定CPU将要操作的内存地址。
    • 数据总线:用来读写内存中的数据。
    • CPU读取内存:先通过地址总线指定内存地址,再通过数据总线来传输数据。
    • 控制总线:用来发送和接收关键信号,比如设备的中断,就绪,复位等信号。
  • 输入输出设备

    • 输入设备:向计算机输入数据。
    • 输出设备:数据计算完,经过输出设备向外界传递。
    • 输入输出设备和CPU传递信号,需要用到控制总线。

线路位宽

数据是通过电压来传递的,低电压为0,高电压为1。如果只有一条线路,每次传一个信号,如果构造1100,就需要传递4次。这种一个bit一个bit发的方式,叫做串行。因此要一次传递多个信号,就需要增加线路。

例如:

一条地址总线,每次就能操作两个内存地址,0或者1。如果10条总线,可以操作1024个地址,如果希望操作4G内存地址,因此需要32条地址总线。串行可以接受,但是每增加一条总线,速度都会翻倍。

64位和32位的计算

场景:32位的CPU,加和两个64位的数。

32位的CPU计算大于32位的数,需要制定相应规则,比较麻烦,因此32位CPU最好操作32位的地址和数据总线。

计算过程:
将64位数拆成两个32位数计算,需要类似我们算数学题,先加和低位,后加和高位,然后加上进位。

而64位CPU可以直接读如64位数,然后进行计算。但是计算小于32位数字,两个CPU性能没区别。

32位CPU最多有32个寄存器,最多操作4G内存地址。

程序执行过程

CPU执行程序:

1. CPU读取PC指针指向的指令,把指令导入指令寄存器
    * 步骤一:CPU的控制单元操作地址总线,指定需要访问的内存地址
    * 步骤二:CPU通知内存设备住被数据,内存设备通过数据总线把数据传入CPU
    * 步骤三:CPU收到内存传来的数据,将数据存入指令寄存器
2. CPU分析指令寄存器的指令,确定类型和参数
3. 如果是计算类型的指令,交给逻辑运算单元计算,如果是存储指令,交给控制单元执行
4. PC指针自增,准备获取下一个指令

Tips: 32位系统,指令指针自增4(因为32位是4Byte)
More:
    1. 指令和数据一般不存在一起
    2. 64位CPU如果只有40条总线,也只能操作2的40次方的CPU地址(约 1T)
    3. 从PC指针读取指令,到执行,到下一个指令的循环,称为CPU指令周期

指令

1. 指令以16进制保存。
2. 构造指令的过程叫指令编码,通常由编译器完成。
3. 解析指令的过程,叫作指令解码,由CPU完成。
4. CPU解码过程:
    I. Fetch(获取): CPU通过PC指针读取对应内存地址的指令
    II. Decode: CPU对指令进行解码
    III. Execution: 执行指令
    IV. Store: CPU将结果存回寄存器或者寄存器存入内存

CPU解析指令的过程

图片来源于参考中的链接
上述四个步骤,叫做CPU的指令周期。

指令的类型

不同类型的指令,参数个数,每个参数位宽都不一样,参数类型分三种:1. 寄存器; 2. 内存地址;3. 数值(整数或者浮点数)

指令从功能角度可划分为以下5类:
1. I/O类型指令:如处理和内存间交换数据的指令store/load等,或者数据从一个地址转移到另一个地址的指令mov
2. 计算类型指令:最多只能处理两个寄存器,比如加减乘除,位运算,比较大小等
3. 跳转类型指令:修改PC指针,例如编程中的:if-esle,switch-case,函数调用等
4. 信号类型指令:比如发送中断的指令trap
5. 闲置CPU指令nop:执行后,CPU空转一个周期

指令可以按照寻址模式区分,例如求和指令,可以分成:
1. 将两个寄存器的值相加的指令add
2. 将一个寄存器和一个整数相加的指令addi

load指令按寻址模式区分:
1. 直接寻址(la):直接加载一个内存地址中的数据到寄存器
2. 寄存器寻址(li):直接将一个数值导入寄存器
3. 间接寻址(lw):将一个寄存器中的数值作为地址,再加载这个地址中的数据

指令的执行速度

CPU是利用脉冲转化为时钟信号驱动的,每一次时钟信号的高低电平的转换,就是一个周期,成为时钟周期。CPU主频,就是时钟信号的频率。比如1GHz的CPU,就是时钟信号的频率是1G。多数指令不能在一个时钟周期内完成。

总结

回到本文最开始,遗留的贯穿全文的问题,64位比32位的优势有哪些?

1. CPU方面:
    a. 64位CPU能执行更大数字的运算
    b. 64位CPU可以寻址更大的内存空间
2. 程序方面:
    a. 指的是指令是32位还是64位。64位机器兼容32位指令,因为只需要兼容机制。而32位机器执行64位指令很难,因为寄存器存不下64位指令
3. 操作系统方面:
    a. 64位操作系统安装不到32位机器

思考

CPU中怎么存对数?
CPU底层不能存对数,只能用逼近法,计算机按照位数,提前设计允许的误差值,
然后用e^x - a不断尝试不同x进行逼近。

参考

全文参考于:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=478#/detail/pc?id=4608


 上一篇
重学操作系统(一) 重学操作系统(一)
重学操作系统(一)前言我准备写一篇文章,记录下我学习操作系统的过程和一些关键知识点。题目是借用了拉钩教育上某个课程的题目[1],感觉很贴切。之所以想学习操作系统,是因为某个面试问了很多jvm,mysql,redis调优以及操作系统相关的问题
下一篇 
Java知识点整理-04 Java知识点整理-04
Java知识点整理-04 Java面向对象-02 前言今天继续写一些关于构造方法的知识点。有时候我们会看到,在创建一个实例的时候,会给实例一个初始值,比如: Food food = new Food("Beef"); 这
2020-05-17
  目录