一种编译器的代码优化调度方法

文档序号:10488790阅读:325来源:国知局
一种编译器的代码优化调度方法
【专利摘要】本发明涉及一种编译器的代码优化调度方法,应用于VLIW类型处理器,该方法包括以下步骤:(1)将代码划分成基本块;(2)对每个基本块建立数据依赖图,所述的数据依赖图包括多个结点和用于连接结点的边,所述的结点表示指令及指令所需要的机器资源,所述的边表示指令之间的数据相关性;(3)对代码进行全局调度;(4)对代码进行拓扑排序。与现有技术相比,本发明具有能更好的适应VLIW处理器等优点。
【专利说明】
一种编译器的代码优化调度方法
技术领域
[0001] 本发明涉及一种代码优化调度方法,尤其是涉及一种编译器的代码优化调度方 法。
【背景技术】
[0002] 数字信号处理器(DSP)是一种特殊结构的微处理器,是专门用来高效率处理数字 信号的处理器,其主要特色是强大的数字运算能力。和通用处理器的架构和微架构相比,专 用数字信号处理器的架构和微架构能够显著提高数字信号的处理速度和效率。数字信号处 理器(DSP)已经成为数字化世界中日益重要的芯片。
[0003] 随着高新技术的快速发展,对数字信号处理器(DSP)的性能和效率要求也越来越 高。超长指令字(VLIW)和单指令流多数据流(snro)等技术已经广泛应用于数字信号处理器 (DSP)的设计中。超长指令字(VLIW)是通过将多条指令组合一起并行执行提高运算速度的 处理器架构。VLIW处理器的利用率取决于编译器的代码优化能力。编译器需要在代码中发 掘出更多的并行性,并优化指令调度,提高指令执行并行度。由于求出对一段代码的最好的 调度方案的算法是一个NP完全问题,所以我们需要求出一个相对最优调度算法。

【发明内容】

[0004] 本发明的目的就是为了克服上述现有技术存在的缺陷而提供一种能缩短程序执 行时间的编译器的代码优化调度方法,运用启发式算法,采用关键路径,机器资源等作为判 断条件,该方法优化的调度了原来并行能力不强的代码,使之更好的适应VLIW处理器。
[0005] 本发明的目的可以通过以下技术方案来实现:一种编译器的代码优化调度方法, 应用于VLIW类型处理器,该方法包括以下步骤:
[0006] (1)将代码划分成基本块;
[0007] (2)对每个基本块建立数据依赖图,所述的数据依赖图包括多个结点和用于连接 结点的边,所述的结点表示指令及指令所需要的机器资源,所述的边表示指令之间的数据 相关性;
[0008] (3)对代码进行全局调度;
[0009] (4)对代码进行拓扑排序。
[0010] 所述的步骤(1)具体为:
[0011] (101)代码进入编译器后生成中间代码,求出中间代码的所有基本块的入口语句, 或者能由条件或者无条件语句转移到的语句,或者紧跟在条件转移语句后面的语句;
[0012] (102)构造每一个入口语句所属的基本块,所述的基本块由一个入口语句到另一 个入口语句之间的语句序列组成,或者由转移语句之间的语句序列组成,或者由停语句之 间的语句序列组成。凡是没有被纳入某一基本块的语句,都是程序中控制流程无法到达的 语句,从而也不会被执行,可以把他从代码中删除。
[0013] 所述的步骤(2)具体为:
[0014] (201)建立集合G= (N,E),N表示结点,E表示边;E中每个e = nl->n2都有标号d,代 表了n2不能在nl执行后d个时钟周期内执行;
[0015] (202)设定没有输出的结点的初始值为0,有输出的结点的值等于与该结点输出边 相连的结点的值加上这两个结点相连的边的值d,若该结点有两个输出边,则选取结点值和 边之和中更大的那个值作为该结点的值。
[0016] 所述的步骤(3)具体为:根据基本块的支配关系移动代码,进行投机性的预测执 行,并更新数据依赖图。基本块的支配关系的描述为:如果从控制流图的入口处到达基本块 的B'的所有路径都经过一个基本块B,那么就认为B支配B'。类似的,如果从B'到达流图出口 的路径都经过B,那么B就反向支配B'。若B支配B'且B'反向支配B,那么B和B'是控制等价的。 在控制等价的两个基本块里,在不违反数据依赖的情况的下进行代码移动,并且更新数据 依赖图。全局调度及预处理完成之后,代码的紧凑性提高。
[0017] 所述的步骤(4)中采用带优先级的启发式函数来调度结点,具体特点如下:
[0018] 1.该启发式函数选取若干个特征值,包括关键路径,资源约束等;
[0019] 2.关键路径是数据依赖图中最长的路径,也就是结点的高度;
[0020] 3.在这几个的特征值中,关键路径的权重最大。
[0021 ]调度一个基本块的过程具体为:
[0022] (401)选取数据依赖图中所有没有输入边的结点,组成集合NoneInput(N);
[0023] (402)初始化package,并将集合None Input (N)中结点值最大的结点加入package, 按照结点值从大到小的顺序,依次检查结点是否满足槽约束条件,并将满足槽约束条件的 结点加入Package,并从集合None Input (N)和数据依赖图中删除,并把这些结点的输出边的 值减一,直到集合None Input (N)为空,则插入Nop指令并结束该package;若两个结点的值相 同,则对那几个值相同的点进行综合考虑:先考虑资源要求更加的严苛的指令,先把要求更 加严苛的指令安放好,然后把资源要求不太严格的指令安放进去。最终要使槽的利用率最 高。若指令组合的效果相同,则按指令在程序出现的顺序来选择。若值相同的结点过多,则 开启一个特定大小的窗口,对窗口里的指令进行选择。直到所有结点均被选择过或者槽数 放满,结束此package,然后开启下一个package。然后,把之前那个package里的结点从 NoneInput(N)集合和数据依赖图中删除,并且把这些结点的输出边上的值减一,若边上的 值为〇,则把此边从E集合中删除,否则保留此边。
[0024] (403)检查数据依赖图,把所有没有输入的结点加入集合NoneInput(N)中,并执行 步骤(402),重复步骤(403)。
[0025] 一个基本块调度完成后,结束当前Package,进入下一基本块,依次执行步骤 (401)、( 402)及(403),直到所有基本块均调度完成。
[0026] 调度的终止判断条件为:在程序开始时,编译器会记录代码未调度时程序需要的 执行时间,当每一次package结束时,对当前执行时间和代码未调度时程序需要的执行时间 进行比较,若当前执行时间〉代码未调度时程序需要的执行时间,则停止调度,并采用未调 度的执行策略。
[0027] 所述的步骤(402)中,若结点值相同的结点数大于或等于5个,则开启一个设定大 小的窗口,对窗口里的指令进行选择,直到所有的结点均被选择过或槽数被放满,则结束此 Package 0
[0028]本发明涉及到的数字信号处理器的体系结构需要满足以下两个条件:
[0029] 1.处理器采用超长指令字(VLIW)设计技术,取指部件一次需要获取η条指令,n>0, 指令长度为2y个字,y> = 0,其中字长可以是任意长度。
[0030] 2.代码不涉及递归函数的调用。
[0031] 与现有技术相比,本发明提出的一种新的启发式算法,采用关键路径,机器资源等 作为判断条件,该算法的输入是一个特殊的数据依赖图,该数据依赖图经过全局调度,并且 加入的结点的值这一概念。在结点的值相对多的时候,采用窗口的模式来形成局部最优的 解。该算法优化的调度了原来并行能力不强的代码,使之更好的适应VLIW处理器,提高代码 的并行性,提高处理器的利用率。
【附图说明】
[0032] 图1为本发明实施例中的代码基本块;
[0033]图2为数据依赖图的结构示意图;
[0034]图3为调度一次后的代码示意图;
[0035]图4为调度两次后的代码示意图。
【具体实施方式】
[0036]下面结合附图和具体实施例对本发明进行详细说明。
[0037] 一种编译器的代码优化调度方法,应用于VLIW类型处理器,该方法包括以下步骤:
[0038] (1)将代码划分成基本块(如图1所示),具体为:(101)代码进入编译器后生成中间 代码,求出中间代码的所有基本块的入口语句,或者能由条件或者无条件语句转移到的语 句,或者紧跟在条件转移语句后面的语句;
[0039] (102)构造每一个入口语句所属的基本块,基本块由一个入口语句到另一个入口 语句之间的语句序列组成,或者由转移语句之间的语句序列组成,或者由停语句之间的语 句序列组成。凡是没有被纳入某一基本块的语句,都是程序中控制流程无法到达的语句,从 而也不会被执行,可以把他从代码中删除。
[0040] (2)对每个基本块建立数据依赖图(如图2所示),数据依赖图包括多个结点和用于 连接结点的边,结点表示指令及指令所需要的机器资源,边表示指令之间的数据相关性;具 体为:
[0041] (201)建立集合G= (N,E),N表示结点,E表示边;E中每个e = nl->n2都有标号d,代 表了n2不能在nl执行后d个时钟周期内执行;
[0042] (202)设定没有输出的结点的初始值为0,有输出的结点的值等于与该结点输出边 相连的结点的值加上这两个结点相连的边的值d,若该结点有两个输出边,则选取结点值和 边之和中更大的那个值作为该结点的值。
[0043] (3)对代码进行全局调度,具体为:根据基本块的支配关系移动代码,进行投机性 的预测执行,并更新数据依赖图。基本块的支配关系的描述为:如果从控制流图的入口处到 达基本块的B'的所有路径都经过一个基本块B,那么就认为B支配B'。类似的,如果从B'到达 流图出口的路径都经过B,那么B就反向支配B'。若B支配B'且B'反向支配B,那么B和B'是控 制等价的。在控制等价的两个基本块里,在不违反数据依赖的情况的下进行代码移动,并且 更新数据依赖图。全局调度及预处理完成之后,代码的紧凑性提高。
[0044] (4)对代码进行拓扑排序,采用带优先级的启发式函数来调度结点,具体特点如 下:
[0045] 1.该启发式函数选取若干个特征值,包括关键路径,资源约束等;
[0046] 2.关键路径是数据依赖图中最长的路径,也就是结点的高度;
[0047] 3.在这几个的特征值中,关键路径的权重最大。
[0048]调度一个基本块的过程具体为:
[0049] (401)选取数据依赖图中所有没有输入边的结点,组成集合NoneInput(N);
[0050] (402)初始化package,并将集合None Input (N)中结点值最大的结点加入package, 按照结点值从大到小的顺序,依次检查结点是否满足槽约束条件,并将满足槽约束条件的 结点加入Package,并从集合None Input (N)和数据依赖图中删除,并把这些结点的输出边的 值减一,直到集合None Input (N)为空,则插入Nop指令并结束该package;若两个结点的值相 同,则对那几个值相同的点进行综合考虑:先考虑资源要求更加的严苛的指令,先把要求更 加严苛的指令安放好,然后把资源要求不太严格的指令安放进去。最终要使槽的利用率最 高。若指令组合的效果相同,则按指令在程序出现的顺序来选择。若值相同的结点过多,则 开启一个特定大小的窗口,对窗口里的指令进行选择。直到所有结点均被选择过或者槽数 放满,结束此package,然后开启下一个package。然后,把之前那个package里的结点从 NoneInput(N)集合和数据依赖图中删除,并且把这些结点的输出边上的值减一,若边上的 值为〇,则把此边从E集合中删除,否则保留此边。
[00511 (403)检查数据依赖图,把所有没有输入的结点加入集合NoneInput(N)中,并执行 步骤(402),重复步骤(403)。
[0052] 一个基本块调度完成后,结束当前Package,进入下一基本块,依次执行步骤 (401)、( 402)及(403),直到所有基本块均调度完成。
[0053]调度的终止判断条件为:在程序开始时,编译器会记录代码未调度时程序需要的 执行时间,当每一次package结束时,对当前执行时间和代码未调度时程序需要的执行时间 进行比较,若当前执行时间〉代码未调度时程序需要的执行时间,则停止调度,并采用未调 度的执行策略。
[0054] 步骤(402)中,若结点值相同的结点数大于或等于5个,则开启一个设定大小的窗 口,对窗口里的指令进行选择,直到所有的结点均被选择过或槽数被放满,则结束此 Package 0
[0055] 本发明涉及到的数字信号处理器的体系结构需要满足以下两个条件:
[0056] 1.处理器采用超长指令字(VLIW)设计技术,取指部件一次需要获取η条指令,n>0, 指令长度为2y个字,y> = 0,其中字长可以是任意长度。
[0057] 2.代码不涉及递归函数的调用。
[0058]根据上述理论,本实施例对如图1所示的代码基本块进行调度,图1的基本块作为 代码的初始输入。图2是数据依赖图,具有结点Nl~N7,按照上面描述的方法,结点的内容包 括它需要的机器资源和结点的值。结点的值的计算方法如上所述,没有输出的结点的值为 0,所以N2,和N7的值为0。有输出的结点的值的等于相连结点的值与边上的值的和。所以N6, N5,N4,N3的值分别为1,2,3,5。Nl有两个输出边,分别指向N2和N5,指向N2的那个路径算出 了来的值为2,指向N5的那个路径算出来的值为4,所以以4作为NI的值。图2中右边的椭圆框 指出了该每条指令所需要的机器资源,这里仅仅以VLIW的槽约束来举例。指令NI,N2,N3, N6,N7只能被安排在23槽,而N4,N5则四个槽都可以被安放。。
[0059]开始调度时,初始化一个VLIW package,这里记为{}。初始时,遍历数据依赖图, NoneInput (N)更新为{NI,N4}。然后开始调度,由于N4的值大于Nl,所以先把N4放入 package,根据槽限制,只能放在2,3槽,所以把M放在第2槽。然后再NoneInput(N)中找出次 长路径,也就是Nl,加入package。根据槽限制,只能放在第三槽。此时,NoneInput(N)为空, 结束此package。此时此package的内容为{Nop,Nop,M,Nl}。
[0060] 调度一次之后的数据依赖图如图3所示,NI,N4从图中删除,这两个结点的输出边 减一。然后遍历数据依赖图,检查是否有新结点加入NoneInput(N)。此时发现没有,所以插 入nop结束此package,此package为{Nop,Nop,Nop,Nop} ·
[0061] 调度两次之后的数据依赖图如图4所示,此时上次值为1的边由于减一变成了 0,从 图中删除。然后重新遍历数据图,此时,NoneInput(N)中为{N2,N4}.同理,选择值更大的N4 先加入package,放在0槽,然后选择N2放入2槽。此时,None Input (N)为空,结束此package。 MpackageS{N4,Nop,N2,Nop}。
[0062] 以此类推。
[0063] 最后调度的结果如表1所示。未调度时代码的执行周期为9个周期,调度之后的执 行周期为6个周期,优化了 3个周期,优化率达到33.3%。
[0064]表1调度结果
[0066] 图2、图3及图4中slot表示槽。
【主权项】
1. 一种编译器的代码优化调度方法,应用于VLIW类型处理器,其特征在于,该方法包括 以下步骤: (1) 将代码划分成基本块; (2) 对每个基本块建立数据依赖图,所述的数据依赖图包括多个结点和用于连接结点 的边,所述的结点表示指令及指令所需要的机器资源,所述的边表示指令之间的数据相关 性; (3) 对代码进行全局调度; (4) 对代码进行拓扑排序。2. 根据权利要求1所述的一种编译器的代码优化调度方法,其特征在于,所述的步骤 (1) 具体为: (101) 代码进入编译器后生成中间代码,求出中间代码的所有基本块的入口语句,或者 能由条件或者无条件语句转移到的语句,或者紧跟在条件转移语句后面的语句; (102) 构造每一个入口语句所属的基本块,所述的基本块由一个入口语句到另一个入 口语句之间的语句序列组成,或者由转移语句之间的语句序列组成,或者由停语句之间的 语句序列组成。3. 根据权利要求1所述的一种编译器的代码优化调度方法,其特征在于,所述的步骤 (2) 具体为: (201) 建立集合G= (N,E),N表示结点,E表示边; (202) 设定没有输出的结点的初始值为0,有输出的结点的值等于与该结点输出边相连 的结点的值加上这两个结点相连的边的值d,若该结点有两个输出边,则选取结点值和边之 和中更大的那个值作为该结点的值。4. 根据权利要求1所述的一种编译器的代码优化调度方法,其特征在于,所述的步骤 (3) 具体为:根据基本块的支配关系移动代码,进行投机性的预测执行,并更新数据依赖图。5. 根据权利要求3所述的一种编译器的代码优化调度方法,其特征在于,所述的步骤 (4) 中采用带优先级的启发式函数来调度结点,调度一个基本块的过程具体为: (401) 选取数据依赖图中所有没有输入边的结点,组成集合Nonelnput (N); (402) 初始化package,并将集合Nonelnput(N)中结点值最大的结点加入package,按照 结点值从大到小的顺序,依次检查结点是否满足槽约束条件,并将满足槽约束条件的结点 加入Package,并从集合Nonelnput (N)和数据依赖图中删除,并把这些结点的输出边的值减 一,直到集合Nonelnput (N)为空,则插入Nop指令并结束该package; (403) 检查数据依赖图,把所有没有输入的结点加入集合N〇neInput(N)中,并执行步骤 (402),重复步骤(403)。6. 根据权利要求5所述的一种编译器的代码优化调度方法,其特征在于,一个基本块调 度完成后,结束当前Package,进入下一基本块,依次执行步骤(401)、(402)及(403),直到所 有基本块均调度完成。7. 根据权利要求5所述的一种编译器的代码优化调度方法,其特征在于,调度的终止判 断条件为:在程序开始时,编译器会记录代码未调度时程序需要的执行时间,当每一次 package结束时,对当前执行时间和代码未调度时程序需要的执行时间进行比较,若当前执 行时间〉代码未调度时程序需要的执行时间,则停止调度。8.根据权利要求5所述的一种编译器的代码优化调度方法,其特征在于,所述的步骤 (402)中,若结点值相同的结点数大于或等于5个,则开启一个设定大小的窗口,对窗口里的 指令进行选择,直到所有的结点均被选择过或槽数被放满,则结束此Package。
【文档编号】G06F9/45GK105843660SQ201610159967
【公开日】2016年8月10日
【申请日】2016年3月21日
【发明人】吴俊 , 李涵, 任浩琪, 张志峰, 赵朝兴, 雷蕾, 常睿
【申请人】同济大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1