指令调度概念原理介绍

指令调度概念原理介绍

​ 指令调度是编译优化中用于提高指令级并行,从而提高在计算机上指令流水线的性能。更直接的说,在没有改变原代码语义的情况下,它做了下面两件事:

1. 通过重排指令顺序避免指令流水线停顿;
2. 避免非法或语义模糊的操作(涉及典型的细微的指令流水线时序问题或非互锁的资源);

​ 指令流水线停顿可能是由结构危险(处理器资源限制),数据危险(输出另一条指令所需的一条指令),控制危险(分支);

​ 为了能产生快速的代码,代码生成阶段重排指令,以照顾目标机器在特定方面的性能约束。

​ 不同操作指令的执行时间可能是不同的。内存访问操作可能需要花费几十甚至数百个CPU周期,但某些算术操作(除除法为例),需要几个CPU周期。这种延迟较长的操作对编译后代码性能的影响可能是惊人的。

​ 以下面的例子来简单说明指令调度:假定目前loadAI或storeAI操作需要3个周期,mult操作需要2个周期,而所有其他操作都只需1个周期。下表给出了一个代码片段,并在开始列给出了每个操作开始执行的周期,在结束列给出了操作完成的时间。

开始列结束列code
13loadAI Rarp, @a => R1 // 加载’a’
44add R1, R1 => R1 // R1 = a * 2
57loadAI Rarp, @b => R2 // 加载’b’
89mult R1, R2 => R1 // R1 = (a * 2) * b
1012loadAI Rarp, @c => R2 // 加载’c’
1314mult R1, R2 => R1 // R1 = (a * 2 * b) * c
1517loadAI Rarp, @d => R2 // 加载’d’
1819mult R1, R2 => R1 // R1 = (a * 2 * b * c) * d
2022storeAI R1 => Rarp, @a // 保存R1到’a’变量

​ 9个操作的指令序列花费了22个周期执行。最小化寄存器的使用并未导致执行变快。

许多处理器都有一种特性,可以在长延迟操作执行期间发起新的操作。只要新操作完成之前不引用长延迟操作的结果,执行都可以正常地进行。但如果某些插入的操作试图过早地读取长延迟操作的结果,处理器将延缓执行需要该值的操作,直至长延迟操作完成。在操作数就绪之前,操作是不能开始执行的,而操作结束之前,其结果也是无法读取的。

​ 指令调度器重排代码中的各个操作。它试图最小化等待操作数所浪费的周期数。当然,调度器必须确保,新指令序列产生的结果与原来的指令序列是相同的。在很多情况下,调度器可以大幅度改进“朴素”代码的性能。对于我们的例子,好的调度器可能产生下列指令序列,如下表:

开始列结束列code
13loadAI Rarp, @a => R1 // 加载’a’
24loadAI Rarp, @a => R2 // 加载’b’
35loadAI Rarp, @a => R3 // 加载’c’
44add R1, R1 => R1 // R1 = a * 2
56mult R1, R2 => R1 // R1 = (a * 2) * b
68loadAI Rarp,@d => R2 // 加载’d’
78mult R1, R3 => R1 // R1 = (a * 2 * b) * c
910mult R1, R2 => R1 // R1 = (a * 2 * b * c) * d
1113storeAI R1 => Rarp, @a // 保存R1到’a’变量

​ 代码的这个版本仅需要13个周期执行。与最小数目相比,该代码使用的寄存器多一个。在这以指令序列中,除8,10,12周期之外,每个周期都开始一个操作。其他等价的调度也是有可能的,但与之等长的调度一般需要使用更多的寄存器。

结束语

​ 正如上面看到的,变异种大多数正真的困难出现在代码生成阶段。而且这些问题相互影响,使得情况更为复杂。例如,指令调度移动load操作,使之远离依赖的load的算术操作。这样做可以增加需要这些值的时间段,但此期间内所需的寄存器的数目也会相应地增加。类似地,将特定的值赋值给特定的寄存器,可以在两个操作之间建立“伪”相关性,从而限制指令调度。(在第一个操作完成之前第二个操作不能调度执行,即使在公用寄存器中的值并无依赖性。重命名该值可以消除这种伪相关性,代价是使用更多寄存器。)

​ 编译器是一个超级复杂的工程。好的编译器合并了来自形式语言理论,算法研究,人工智能,系统设计,计算机体系结构和程序设计语言理论的思想,并将其应用到程序转换的问题上。

​ 征服编译器很困难,加油吧。。。

参考

《Engineering a Compiler》

https://en.wikipedia.org/wiki/Instruction_scheduling

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值