标签:bit https 保存 val through strong ack 实现 变量
本文是阅读《大话处理器》的读书摘要
流水线存在的意义在于尽可能的让所有硬件都不空闲,从而提高整个系统的处理能力
简单的三级流水线:
MIPS 的五级流水线
导致流水线出现停顿的因素称为冒险(Hazard)
以 MIPS 为例,旧的 MIPS CPU 没有片内 cache,指令和数据放在了一起,这样 IF 和 MEM 流程会发生冲突,两者之一需要等待另一个命令的完成,这样就影响了流水线的效率,最少 IF 模块或者 MEM 模块不能同时执行,违背的流水线的初衷。现在的 CPU 一般一级缓存分为指令和数据两块,不会出现这种情况
以两条相邻的指令为例:
add R1,R2,R3 ; R1 = R2+R3
add R4,R1,R5 ; R4 = R1+R5
按照 MIPS 的五级流水线,如果不做任何处理,流程如下
CMD | Cycle1 | Cycle2 | Cycle3 | Cycle4 | Cycle5 |
---|---|---|---|---|---|
add R1,R2,R3 | IF | ID | EX | MEM | WB |
add R4,R1,R5 | IF | ID | EX | MEM |
第二条指令的 EX 是在第一条指令 WB 之前执行的,结果是错误的。简单的解决方法是在这两条指令之间加 NOP 操作,将第二条命令的流水线后移;高效的方法是直通,系统检测到这种情况后后面的指令直接从寄存器取值而不是寄存器堆
控制冒险指的是指令中的跳转语句造成部分流水线操作的失效,这是 CPU 中引入分支预测与乱序执行模块的原因
2 位预测,即在跳转指令处维护一个 2bit 的计数器,每次跳转计数器加 一,否则减一
CPU 在执行到跳转指令处时,如果计数器值为2/3,则解析跳转指令后的命令,否则解析其他跳转后的命令;如果预测失败,则部分流水线会被清空
CPU 核心有专门的分支预测模块,用于保存计数器与跳转地址等信息
除了减少流水线冒险而引入乱序执行,CPU 和内存之间的数据交换一般需要数百个 Cycle,cache 未命中时从内存读数据是非常耗时的,所以一旦出现这种情况,处理器不应该等待内存读写,而是去处理其他任务,数据准备好后再执行未完成的任务,这是 CPU 乱序执行的另一个原因
指令乱序执行的前提是前后指令没有相关性,比如x=a+b;y=x+c
这两条指令是相关的,但x=a+b;y=c+d
这两条指令就不相关,指令是否可以执行依赖于两个条件
从指令和数据这两个维度,可以将处理器结构分为下面四类
指令并行有两大类,超标量和 VLIW
||
运算符告知编译器部分指令可以并行执行这两种实现方式,VLIW 更好一些,编译器可以使用额外的信息进行优化,x86 因为兼容性问题,才选择使用超标量
软件编程领域的线程切换一般由操作系统实现,系统会保存线程的上下文
硬件多线程的切换由硬件自行完成,速度与效率要远高于软件多线程,这两者有概念上的区别,注意区分
CPU Cache 存在的前提是时间局部性(刚访问的数据随后被访问的概率大)与空间局部性(相邻的数据均被访问的概率大于不相邻的数据)
多核 CPU 一般有三级缓存,一二级缓存是 Core 独占的,一级缓存速度最快,一级缓存一般将数据和指令分开,避免上面所说的流水线结构冒险;三级缓存是多个 Core 共享
x86 CPU 中的 Cache 一般对程序员而言是透明的,但 DSP 则不同,DSP 片内 Cache 程序可以直接使用
Cache 被分为若干个等大小的块(32Byte、64Byte),这些块被称为 Cache line,Cache line 是 Cache 和内存交换数据的最小单元
Cache 与内存的同步有两类
为了保证 Cache 一致性,处理器提供了两个保证底层一致性的操作:置无效和写更新
写更新比置无效更耗时
MESI 协议使用 2 bit 来描述 Cache 的 4 中状态
标签:bit https 保存 val through strong ack 实现 变量
原文地址:https://www.cnblogs.com/jiahu-Blog/p/13232899.html