寄存器、内存和CPU

305 阅读8分钟

本人计算机科学小白,有理工科基础,课程来源是《计算机科学速成课》

B站链接:www.bilibili.com/video/BV1EW…

文章中的图部分来源视频截图,部分自绘,使用软件:画图、亿图图示(画电路图非常方便)。

封面是旧都なぎ老师ヾ(>∀<)(ノ∀`●)⊃老师的画风真是太好看了!

6 寄存器&内存

ALU输出的数据,还需要存下来,否则就没有意义。

RAM:随机存取存储器。只能在有电的情况下存储东西。

memory:持久存储。电源关闭时数据也不会丢失。

上一节中接触的电路都是单向流通的,那么如果将输出和输入的其中一个连接起来,会发生什么事?

红色:A为1,B为0时,输出为1,B变成1,所以输出仍为1

橙色:A为0,B为0时,输出为0

绿色:A为1,B为1时,输出为1

image-20210603145315346.png

从而我们得到了一个输出永远为1的电路,但是这是永久的,无法从1变回0。

image-20210603145739874.png 同理可得,该电路与OR电路的结果相反,无论A输入什么,输出永远为0。

现在有了记录1和记录0的电路,将两者结合起来,就有了锁存器

AND-OR 锁存器

有两个输入,“设置”输入,把输出变为1,如红色;“复位”输入,把输出变为0,如绿色。

如果“设置”和“复位”都是0,电路会输出最后放入的内容。

image-20210603150425778.png

也就是说,它存储了一位值,叫做锁存,因为是锁定了一个值。

写入:放入数据

读取:拿出数据

但是实际使用中,两条线太麻烦,希望能够只有一条输出线,设置为0或1来存储值,另一条线决定是否启用,未启用时就锁定,叫做允许写入线

加入另外的一些逻辑门,叫做门锁,可以打开或关上。

绿色:启用;红色:锁定。

image-20210603151716009.png

将上图电路缩放为一个“盒子”。

红色:不允许写入时,输出永远为0,

绿色:允许写入,写入1,输出为0。

此时再将允许写入更改为0,输出不变,锁定。不管给数据输入线什么值,都不会变化输出,成功将值存储了起来。

image-20210603152525917.png

但是这个锁存器是一位的,并排放8个锁存器,就可以存储八位数据。此时叫做寄存器

写入寄存器之前,要启用里面所有的锁存器。用一根线连接所有“允许输入线”,把它设为1,然后用8条数据线发数据,将“允许写入线”设回0。成功将八位的值存起来。

如果只有很少的位,把锁存器并排放置,也勉强够用。

但是,现在所用的寄存器都有256位的了,这样就需要513条线了。

解决方法是使用矩阵

256位的寄存器,我们用16×16网格的锁存器,有16行16列。启用某个锁存器就使用该锁存器的坐标。将该锁存器的行线和列线由AND门连接到允许写入线,行线和列线均为1时,AND门才输出1。

类似的想法可以应用于允许读取线。

经过优化,可以发现此时256位寄存器只需要35根线(一根数据线,一根允许写入线,一根允许读取线,16行线,16列线)就可以完成需要的操作。

多路复用器:将地址转成行或列。

256位需要两个多路复用器,一个选定行,一个选定列。选定的方式是四位地址作为第几行,四位地址作为第几列,所以地址需要8位。

image-20210603154328343.png

但是256位的仍然做不到什么事,所以需要继续扩大规模。

为了存一个8位数字,我们需要同时给8个256位内存一样的地址,每个地址存1位,总共能存256个字节。

RAM内存:随机存取存储器

(原来微机原理课上的8位地址是这么来的ヽ(ー_ー)ノ)

image-20210603154514725.png

内存的重要特性:可以随时访问任何地址

7 中央处理器

计算机的心脏:中央处理单元,简称CPU。

程序也可以存在内存里。可以给CPU支持的所有指令,分配一个ID。

指令地址寄存器:追踪程序运行到哪里了。

指令寄存器:存当前指令。

CPU的第一阶段:取指令阶段

负责拿到指令,将指令地址寄存器连到RAM,由指令地址寄存器告知需要的地址,返回地址的值,将该值复制到指令寄存器内。

第二阶段:解码阶段

指令是八位二进制,前四位是操作码,指令由控制单元进行解码,需要有一个电路识别操作码是否为相应指令的码。后四位是RAM的地址。

第三阶段:执行阶段

经过解码后运行前四位决定的指令,并对后四位对应地址的值进行操作,如LOAD_A指令是将获得的值放入寄存器A。

将刚刚的控制电路简化为一个控制单元。

【这里有四个例子,观看视频体会比较好】

计算机中,时钟用于管理CPU的节奏。时钟以精确的间隔,触发电信号,控制单元会用这个信号,推进CPU的内部操作。

时钟速度:取指令→解码→执行(单位是赫兹)

1赫兹=一秒1次时钟周期,1GHZ=一秒10亿次时钟周期

超频:加多每秒的时钟周期,但是容易出现混乱。

降频:利于省电,对电池好。

8 指令和程序

JUMP指令:跳转指令。操作方法是把指令的后四位表示的内存地址的值覆盖掉指令地址寄存器里的值。

JUMP_NEGATIVE指令:有条件的跳转。当ALU里输出为负时跳过。

HALT指令:停止。

如果JUMP没有条件的话,容易造成死循环,无法停止。所以需要有条件的JUMP。

但是现在我们的CPU,只有四位指代指令,四位指代地址,局限性大。所以需要更多位来表示。

解决这个问题一是加长指令长度,二是可变指令长度

可变指令长度可以让指令为任意长度。

【有视频指令执行流程,还是多看视频体会】

9 高级CPU设计

早期计算机提速方式:减少晶体管的切换时间。

但是上节的指令挨个加减操作比较麻烦,所以可以考虑使用乘除来简化计算量。

现在随处可见的一些操作,如果由时钟周期做的话,太多太复杂,势必影响速度。为了让读取更快一些,在CPU里加入了缓存,能够让RAM传数据时可以一坨一坨传,CPU需要处理数据时,可以直接从缓存挨个拿,CPU可以不用等待从RAM传数据的时间了。

缓存命中:想要的数据已经在缓存中了。反之成为缓存未命中

(也就是多了一个临时空间)

而CPU输出的数据也会暂时先存在缓存中,再交给RAM。此时就出现一个问题,缓存和RAM不一致,需要记录下来进行同步,所以缓存里的每块空间都有一个特殊标记,叫脏位

同步发生在当缓存满了,CPU又要缓存时,清理缓存腾出空间之前,会先检查脏位,如果是“脏”的,在加载新内容时,先把数据写回RAM。

另一种提升性能的方法:指令流水线

主要方法是并行处理,A干一件事时,可以同步B干另一件事提高效率。

CPU的处理也是按照顺序走的,取址→解码→执行→取址→解码→……

所以可以让CPU重叠进行以节约运行时间。

取址1→解码1 & 取址2→执行1 & 解码2→……

但是也会存在两个问题。

  1. 正在读取时,会受其他指令影响这个数值,从而导致问题,需要停工。这就需要调查数据依赖性,动态排序,最小化流水线的停工时间。

  2. 条件跳转,改变程序的执行流,传统会等待最终输出值再判断,但是如果重叠进行,会导致取出错误的值。解决这个问题是CPU会提前预测值的大小,判断JUMP是否运行哪个概率大一些,提前把指令放进流水线,叫推测执行。如果CPU猜对了,可以立马执行,如果CPU猜错了,立刻清空。为了减少CPU猜错的情况,有了分支预测。现代CPU基本上正确率可达90%。

但是以上方法都是只优化了一个指令流的吞吐量。

另一种提升性能的方法,是同时运行多个指令流,也就是多核处理器。也就是说,一个CPU芯片里,有多个独立处理单元。就像是有多个CPU一起处理,但是由于是多核的,可以共享一些缓存,便于合作运算。

多核还不够的话,可以用多个CPU。

处理器不仅优化了速度,还可以处理更多复杂的操作。