Jam*_*mes 19 assembly mips pipelining
因此,根据我对延迟槽的理解,它们在调用分支指令时发生,并且分支之后的下一条指令也从内存加载.这有什么意义?在分支被采取的情况下,你不希望分支后的代码不运行吗?是否节省时间,以防分支机构没有被采取?
我正在查看管道图,看起来分支后的指令正在进行中..
old*_*mer 23
目前大多数处理器都使用流水线.H&P书中的想法和问题随处可见.在那些原始着作的时候,我会假设实际的硬件与管道的特定概念相匹配.获取,解码,执行,回写.
基本上,管道是装配线,在生产线上有四个主要阶段,因此您最多只能同时处理四个指令.这混淆了执行指令需要多少时钟的概念,它需要多个时钟,但如果你有一些/多个并行执行,那么"平均"可以接近或超过每个时钟一个.
虽然装配线失败,但是当你采取分支时.必须抛出提取和解码阶段中的指令,并且必须再次开始填充,因此您需要几个时钟来获取,解码,然后再执行.分支阴影或延迟槽的想法是恢复其中一个时钟.如果声明分支之后的指令总是被执行,那么当执行分支时,解码槽中的指令也会被执行,取指槽中的指令被丢弃,你有一个时间空洞而不是两个.因此,不是执行,清空,清空,执行,执行,而是在管道的执行阶段执行,执行,清空,执行,执行.... 该分支的痛苦减少了50%,整体平均执行速度提高了等等.
ARM没有延迟槽,但是通过声明程序计数器是前面的两条指令,它也给出了管道的错觉.任何依赖于程序计数器(pc相对寻址)的操作必须使用前面两条指令的pc计算偏移量,对于ARM指令,这对于原始拇指4字节是8字节,当你添加thumb2指令时它会变得混乱.
这些是学术界之外的幻想,管道更深,有很多技巧等,以便遗留代码继续工作,和/或不必重新定义指令如何适用于每个架构的变化(想象一下mips rev x,1个延迟槽,2个延迟槽,如果条件a则转3个槽,如果条件b则转2个槽,如果条件c则转1个槽)处理器继续执行分支后的第一个指令,并丢弃另一个在重新填充管道之后打了十几打.管道的实际深度通常不会与公众分享.
我看到有关这是一个RISC的评论,它可能已经开始,但CISC处理器使用相同的精确技巧,只是给出传统指令集的错觉,有时CISC处理器只不过是一个RISC或VLIW核心用于模拟传统CISC指令集(微编码)的包装器.
观看它制作的节目.可视化装配线,该行中的每个步骤都有一个任务.如果生产线中的一个步骤用尽了蓝色的产品,并且要制作蓝色和黄色的产品,那么您需要蓝色的产品.你不能再换一个新的蓝色星期,因为有人搞砸了.因此,您必须停止生产线,将耗材更改为每个阶段,并将红色和绿色产品暂时生产,这通常可以在不倾倒生产线的情况下正确分阶段进行.这就像一个分支,在装配线深处的某个地方发生的事情,导致线必须改变,转储线.延迟槽是一种恢复一个产品必须在生产线中丢弃的方法.在生产线停止之前,N + 1产品不再出现,而是在每次生产运行中出现N + 1产品.代码的执行就像生产运行的爆发一样,在命中分支到另一个短执行路径之前,你经常得到短的,有时很长的线性执行路径,分支另一个短的执行路径......
Oli*_*rth 12
在分支被采取的情况下,你不希望分支后的代码不运行吗?
但现在已经太晚了.CPU管道的整个目的是您希望在每个周期完成一条指令.实现这一目标的唯一方法是每个周期获取一条指令.因此,在CPU注意到必须采取分支之前,分支指令之后的代码已经被提取并且正在进行中.
这有什么意义?
无关紧要.它不是一个功能,它只是这种管道设计的工件.
RISC架构的想法是简化解码并优化流水线以提高速度.CPU尝试通过流水线操作重叠指令执行,因此一次执行多条指令.
延迟时隙的要点特别是执行已经通过管道的一部分的指令,并且现在处于一个否则必须被丢弃的槽中.
优化器可以在分支目标处获取第一条指令并将其移至延迟槽,使其"免费"执行.
该功能并未成为主流,主要是因为世界标准化了现有的ISA 1设计,即x86和x86-64,但也出于另一个原因.
晶体管数量的二次爆炸使非常复杂的解码器成为可能.无论如何,当架构上可见的ISA被转换为微操作时,像延迟槽这样的小黑客变得不重要.
在流水线实施的教科书示例中,CPU 提取,解码,执行和回写。这些阶段均在不同的时钟周期内发生,因此实际上,每条指令均在4个周期内完成。但是,当第一个操作码即将被解码时,下一个操作码将从内存中加载。当CPU完全占用时,有4个不同指令的一部分同时处理,并且CPU 的吞吐量是每个时钟周期一个指令。
在机器代码中时,有一个序列:
sub r0, #1
bne loop
xxx
Run Code Online (Sandbox Code Playgroud)
处理器可以从的写回阶段sub r0, #1
到的执行阶段反馈信息bne loop
,但是同时xxx已经在获取阶段。为了简化展开管线的必要性,CPU设计人员选择使用延迟槽。在获取延迟时隙中的指令之后,获取单元具有分支目标的正确地址。优化的编译器很少需要在延迟槽中放入NOP,而是在其中插入两个可能的分支目标都必需的指令。