循环的软流水原理和实例展示

时间:2022-12-17 09:31:16

软流水的原理: 

1.分解同一循环内的指令相关,把指令软件方式重排, 实现指令的流水。

2. 重排后的指令,以抽取的不同次的循环代码为主体进行新的循环。

3. 由于打乱了原来的指令的顺序,比如store操作出现在了Load操作之前(当然,这个load其实是下一次循环的load),需要在新的循环进入之前有装入代码来喂饱第一次循环的store,而在新循环结束时,最后一次循环的Load指令获得的数据还没有store,所以还需要额外的排空代码。


软件流水目前没有很常见的标准的做法,现提供一个比较简单和容易理解的方式来手工实现软流水。


例子是龙芯设计师胡伟武老师的《计算机体系结构》一书的习题,代码如下;

循环的软流水原理和实例展示


我的思路和方法,不想码字了,,,写在了纸上,有点乱,字也差,希望不影响阅读。

循环的软流水原理和实例展示

为了方便大家理解,我简单说下过程:

1.画结构图:根据指令的依赖关系和代码顺序,画程序(指令)结构图,同一层的指令可以合并来处理,他们内部的顺序无所谓。这样可以简化接下来的过程。

2.循环展开:将旧循环展开几次,横着写,具体需要展开的次数,和装入代码的Load指令数有关,要确保装入代码的load的操作数可以在新的循环(竖着看,画圈的地方)结束前被store完。 根据我们的这个题目,首先新循环(画圈的地方)需要展开3次,为了能把新循环展开3次,我们的旧循环(横着看)需要展开6次。

3.确定新循环主体:竖着的画圈的指令,从上往下的顺序就是新循环的循环主体,新循环里的指令的地址下标,是接下来要确定的,也是最关键的一步。指令的下标多少,需要选一个参考点,这里选取排空代码第一行(也就是旧循环的第四次循环)为基点0,然后根据这个往上倒推,可以确定新循环的第一个store指令的地址下标为-24.然后再根据这个基点,确定新循环的其他指令的地址下标,最后加上原来的循环开销指令,就完成了新循环的主体。

4.装入代码:圆圈的左上角的指令都是装入代码,按照从上往下的顺序写下来,地址下标,根据旧循环次数一次变化,在最后一步,更新地址值时,要确保新的地址值在进入新循环时和store指向的地址对应(比如新循环的第一个store存的是第一个0(R1)的load值,而当前store -24(R1),所以R1的值在装入代码最后一步,需要加24。或者换种理解:因为前面装入代码的过程是旧循环的3次展开,所以最后R1的下标递增时应该是8*3=24了)。

5.排空代码:圆圈的右下角就是排空代码。从上往下顺序写下来。因为新循环展开了3次,所以最后的排空代码开始时的store的地址下标是-24,这样刚好把在新循环里面load的值的地址对应起来了,存的数据也就不会错了。(可以看出一个规律,新循环主体的第一个store的下标和排空指令的第一个指令下标其实是一样的。)


经过以上步骤,就可以实现一个正确的软流水了。是不是感觉软流水也没那么复杂了呢?