纸带:一个一个连续的格子存放数据;
读写头:读取纸带上格子字符,读写头上有一些部件,比如存储单元、控制单元及运算流程
1、存储单元用于存放数据; 2、控制单元用于识别字符是数据还是指令,以及控制程序的流程等; 3、运算单元用于执行运算指令。
程序和数据存储在内存,存储的区域是线性的,存储数据的基本单位是字节byte,一字节等于8位,1byte=8bit
CPU 32 位和 64 位,通常称为 CPU 的位宽,代表的是 CPU 一次可以计算(运算)的数据量。
CPU内部有寄存器、控制单元和逻辑单元,控制单元用于控制CPU工作,逻辑单元负责计算、寄存器可以分为多个种类,每种寄存器功能不同:
为什么需要寄存器,内存离CPU太远了,寄存器在CPU中,离控制单元逻辑单元近
总线是用于CPU和内存以及其他设备之间的通信:
输入设备向计算机输入数据,计算机经过计算后,把数据输出给输出设备。期间,如果输入设备是键盘,按下按键时是需要和 CPU 进行交互的,这时就需要用到控制总线了。
数据是如何通过线路传输的呢?其实是通过操作电压,低电压表示 0,高压电压则表示 1。
为了避免低效率的串行传输的方式,线路的位宽最好一次就能访问到所有的内存地址。
如果计算的数额不超过 32 位数字的情况下,32 位和 64 位 CPU 之间没什么区别的,只有当计算超过 32 位数字的情况下,64 位的优势才能体现出来。
①:CPU读取【程序寄存器】的值(指令内存地址),【控制单元】操作【地址总线】找到对应程序内存地址,通知内存设备准备好数据,数据通过【数据总线】传给CPU,存入【指令寄存器】;
②:【程序寄存器】的值自增,表示指向下一条指令。自增大小由CPU位宽表示,32位增4字节。
③:CPU分析【指令寄存器】确定指令类型和数据,交给【逻辑运算单元】。
一个程序执行的时候,CPU 会根据程序计数器里的内存地址,从内存里面把需要执行的指令读取到指令寄存器里面执行,然后根据指令长度自增,开始顺序读取下一条指令
CPU中寄存器,处理速度是最快的,但是能存储的数据也是最少
CPU Cache称为CPU告诉缓存,通常会分为 L1、L2、L3 三层:
L1 Cache 通常分成「数据缓存」和「指令缓存」,L1离CPU最近,且最小
一个内存的访问地址,包括组标记、CPU Cache Line 索引、偏移量这三种信息
形式一用 array[i][j]
访问数组元素,形式二的 array[j][i]
来访问,形式一更快
按照内存布局顺序访问,将可以有效的利用 CPU Cache 带来的好处,这样我们代码的性能就会得到很大的提升。
如果分支预测可以预测到接下来要执行 if 里的指令,还是 else 指令的话,就可以「提前」把这些指令放在指令缓存中,这样 CPU 可以直接从 Cache 读取到指令,于是执行速度就会很快。
如果一个线程在不同核心来回切换,各个核心的缓存命中率就会受到影响,
当有多个同时执行「计算密集型」的线程,为了防止因为切换到不同的核心,而导致缓存命中率下降的问题,我们可以把线程绑定在某一个 CPU 核心上,这样性能可以得到非常可观的提升。
CPU Cache 作为内存与 CPU 之间的缓存层,CPU访问数据先从 CPU Cache 中找,如果缓存命中直接返回数据。如果 CPU Cache 里面没有,要从内存中每一读取一块的数据放到 CPU Cache 中。内存映射到 CPU Cache :把内存地址拆分成 [索引+组标记+偏移量]的方式。
CPU Cache不仅需要读取数据,修改后还要同步数据,就是把cache数据同步到内存
把数据同时写入内存和 Cache 中,这种方法称为写直达,每次写操作都会把数据写回到内存,而导致影响性能
当发生写操作时,新的数据仅仅被写入 Cache Block 里,只有当修改过的 Cache Block「被替换」时才需要写到内存中,
在把数据写入到 Cache 的时候,只有在缓存不命中,同时数据对应的 Cache 中的 Cache Block 为脏标记的情况下,才会将数据写到内存中,而在缓存命中的情况下,则在写入后 Cache 后,只需把该数据对应的 Cache Block 标记为脏即可,而不用写到内存里。
由于 L1/L2 Cache 是多个核心各自独有的,那么会带来多核心的缓存一致性(Cache Coherence) 的问题
串行化需要保证核心C和D都能看到相同顺序的数据变化,这里就要使用锁了。
写传播的原则就是当某个 CPU 核心更新了 Cache 中的数据,要把该事件广播通知到其他核心。最常见实现的方式是总线嗅探(Bus Snooping)。
总线嗅探:保证某个 CPU 核心的 Cache 更新数据这个事件能被其他 CPU 核心知道。
MESI协议:基于总线嗅探机制实现了事务串行化,也用状态机机制降低了总线带宽压力,这个协议就是 MESI 协议,这个协议就做到了 CPU 缓存一致性。
整个 MSI 状态的变更,则是根据来自本地 CPU 核心的请求,或者来自其他 CPU 核心通过总线传输过来的请求,从而构成一个流动的状态机。另外,对于在「已修改」或者「独占」状态的 Cache Line,修改更新其数据不需要发送广播给其他 CPU 核心。
CPU Cache Line 是 CPU 从内存读取数据到 Cache 的单位。 L1 Cache 一次载入数据的大小是 64 字节。