发明内容
基于上述技术问题,本发明的主要目的之一在于提出一种异构多核程序的编译方法,以便于简化异构多核处理器的编译过程,提升程序员的开发效率。
为了实现上述目的,本发明提供了一种异构多核程序的编译方法,包括以下步骤:
步骤1,将一个程序代码分解成若干个运行在不同指令集体系结构处理器核上的程序代码;
步骤2,将分解后的所述程序代码发送到对应指令集体系结构下的编译器上进行预编译,得到各自对应的二进制代码组;对所述二进制代码组进行完整性检测,如果发现含有未定义函数符号,则报错并结束本方法,如果未发现则跳至步骤3;
步骤3,通过逐层查找的方法,自顶向下的建立函数调用关系数据库;
步骤4,对所述二进制代码组中的每个二进制代码生成相应的调度代码,对除最底层之外的二进制代码组中的每一个二进制代码进行未定义函数符号检查并生成所述未定义函数符号的定义;
步骤5,检查所述二进制代码组中的函数是否带有参数,对于带有参数的函数插入参数拷贝代码,从而生成参数准备代码;
步骤6,将所述二进制代码组分别用其对应的指令集体系结构编译器进行再编译,用以检查并生成整个异构多核程序的可执行程序;
步骤7,将各个层次编译出的可执行程序集合和所述函数调用关系数据库封装成程序安装包。
其中,步骤1包括:
将输入的程序代码进行着色,按照颜色分解成多个程序代码,着色/分解的最小粒度为一个函数,其中每种颜色表示一种指令集体系结构;
分解后的程序代码包含多个程序代码组,将分解后的程序代码组按颜色和颜色对应的指令集体系结构层次排序成第1层到第n层程序代码组,其中n为自然数;
每个层次的程序代码组中包含一个或多个程序代码,每个程序代码对应生成一个可执行程序,每个程序代码中包含一个或多个相同颜色的函数;
将分解且分组后的层次化程序代码组放入步骤2的输入中,跳至步骤2。
其中,步骤2包括:
将输入的n个程序代码组分别用各个层次的指令集体系结构编译器编译,得到n个二进制代码组,每个二进制代码组与程序代码组一一对应,且组内的二进制代码与程序代码一一对应;
对所述二进制代码组进行完整性检测,如果第n层二进制代码组不含有未定义函数符号,则跳至步骤3;如果第n层二进制代码组含有未定义函数符号,则预编译失败,该方法结束。
其中,步骤3包括:
检查从第n-1层到第1层的每个二进制代码组i中的每个二进制代码,如果其包含未定义函数符号,则用此符号在i+1层二进制代码组中定义的函数符号中做匹配查找,若有且只有一个,则新建一个调用关系加入到函数调用关系数据库中;若有超过一个,则函数调用关系数据库生成失败,该方法结束;若没有,则函数调用关系数据库生成失败,该方法结束。
其中,步骤4包括:
检查从第n-1层到第1层的每个二进制代码组i中的每个二进制代码,如果存在未定义的函数符号,则生成该函数的定义;在第i层的程序代码组里的二进制代码中插入生成的函数定义;将修改后的n个程序代码组传递给步骤5,并跳至步骤5。
其中步骤4中所述函数的定义内容包括:装载、启动第i+1层包含该函数符号的二进制代码,以及在串行方式下第i+1层代码执行完成的阻塞等待信息。
其中,步骤5包括:
检查从第n-1层到第1层的每个源代码组i中的每个源代码,如果存在步骤4生成的函数定义,则检查函数原型是否有参数,如果无参数则跳过,如果带参数,则在生成的函数定义中,生成从第i层到第i+1层的参数拷贝代码,在启动第i+1层包含该函数符号的二进制代码之前,插入生成的参数拷贝代码;
生成第i+1层参数准备代码,在第i+1层包含该函数符号的二进制代码对应的程序代码之前插入生成的参数准备代码;
将修改后的程序代码组传递给步骤6,并跳至步骤6。
其中,步骤6包括:
将输入的n个源代码组分别用各个层次的指令集体系结构编译器编译,如任何一个层次的编译器返回错误,则返回错误,否则输出n个层次二进制代码组到步骤7,跳至步骤7。
其中,步骤7包括:
从所述函数调用关系数据库中导出所述异构多核程序的所有调用关系表,作为加载信息与第1层二进制代码组合并封装成可执行程序,将第2层到第n层二进制代码组分别加入各层次的函数库中,若对应层次的函数库不存在,则新建一个所述层次的函数库;将各个层次编译出的可执行程序集合和所述函数调用关系数据库封装成一个程序安装包。
其中,所述编译方法用于层次化异构多核处理器中。
基于上述技术方案可知,本发明的编译方法包括代码着色和代码分解步骤、预编译步骤、调度代码生成步骤、参数传递代码生成步骤、控制流关系数据库生成步骤、后编译步骤和程序发布步骤,可以极大地减小程序员在异构多核处理器下的开发难度,提升开发效率。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚明白,以下结合具体实施例,并参照附图,对本发明作进一步的详细说明。
本发明公开了一种编译两种或两种以上指令集体系结构的层次化异构多核处理器程序的方法。层次化异构多核处理器是指处理器程序中包含若干种指令集体系结构,每种指令集体系结构由若干个程序组成,每种指令集体系结构的程序的集合构成一个层次,每一个层次受其上一个层次的程序控制,并且控制其下一个层次的程序。该编译方法包括:
代码着色和代码分解步骤,用于将一个程序代码分解成若干个运行在不同指令集体系结构处理器核上的程序代码,即不同层次上的程序代码;
预编译步骤,用于分析处理器核之间存在的控制流关系和数据流关系;
调度代码生成步骤,用于自动生成和插入各层次程序之间调用、同步等功能的代码;
参数传递代码生成步骤,用于自动生成和插入不同层次之间程序调用时的数据交换代码;
控制流关系数据库生成步骤,用于根据各个层次最终编译出的程序在执行时的调用关系建立关系数据库;
后编译步骤,用于将插入了自动生成代码的各层次程序代码用该层次指令集编译器编译成程序集合;以及
程序发布步骤,用于将各个层次编译出的程序集合和关系数据库封装成程序安装包。
下面分别详述之。
步骤1,代码着色和代码分解步骤
将输入的源代码进行着色,按照颜色分解成多个源代码,着色/分解的最小粒度为一个函数,其中每种颜色标示一种指令集体系结构;分解后的源代码包含多个源代码组,将分解后的源代码组,按颜色和颜色对应的指令集体系结构层次排序成第1层到第n层源代码组;每个层次的源代码组中包含一个或多个源代码(第1层指令集体系结构的源代码有且只有一个源代码),每个源代码对应生成一个可执行程序,每个源代码中包含一个或多个相同颜色的函数。将分解且分组后的层次化源代码组放入步骤2的输入中,跳转到步骤2。
步骤2,预编译步骤
将输入的n个源代码组分别用各个层次的指令集体系结构编译器编译,得到n个二进制代码组,每个二进制代码组与源代码组一一对应,且组内的二进制代码与源代码一一对应,每个二进制代码包含一个或若干个定义的函数符号,以及一个或若干未定义符号。若第n层二进制代码组不含有未定义符号,跳转到步骤3。若第n层二进制代码组含有未定义符号,则预编译失败,该方法结束。
步骤3,控制流关系数据库生成步骤
从第n-1层到第1层的每个二进制代码组i中的每个二进制代码,若其包含未定义的函数符号,则用此符号在i+1层二进制代码组中定义的函数符号中做匹配查找,若有且只有一个,则新建一个调用关系加入到控制流关系数据库中,该关系的调用者是当前二进制代码组i中的二进制代码,被调用者是i+1层二进制代码组中包含函数符号的二级制代码。若有超过一个,则控制流关系数据库生成失败,有重定义异构多核函数,该方法结束;若没有,则控制流关系数据库生成失败,有未定义的异构多核函数,该方法结束。
步骤4,调度代码生成步骤
从第n-1层到第1层的每个二进制代码组i中的每个二进制代码x,如果存在未定义的函数符号,则生成该函数的定义,定义内容包括装载、启动第i+1层包含该函数符号的二进制代码y,以及(串行方式下)第i+1层代码执行完成的阻塞等待信息。在第i层的源代码组里的二进制代码x的中插入生成的函数定义。将修改后的n个源代码组传递给步骤5,并跳转到步骤5。
步骤5,参数传递代码生成步骤
从第n-1层到第1层的每个源代码组i中的每个源代码x,如果存在步骤4生成的函数定义,则检查函数原型是否有参数,如果无参数则跳过,如果带参数,则在生成的函数定义中,生成从第i层到第i+1层的参数拷贝代码,在启动第i+1层包含该函数符号的二进制代码y之前,插入生成的参数拷贝代码。生成第i+1层参数准备代码,在第i+1层包含该函数符号的二进制代码y对应的源代码之前插入生成的参数准备代码。将修改后的源代码组传递给步骤6,并跳转到步骤6。
步骤6,后编译步骤
将输入的n个源代码组分别用各个层次的指令集体系结构编译器编译,如任何一个层次的编译器返回错误,则返回错误,否则输出n个层次二进制代码组到步骤7,跳转至步骤7。
步骤7,程序发布步骤
从控制流关系数据库中导出该异构多核程序的所有调用关系表,作为加载信息与第1层二进制代码组合并封装成可执行程序,将第2层到第n层二进制代码组分别加入各层次的函数库中,若对应层次的函数库不存在,则新建一个该层次的函数库。程序发布时,包含一个可执行程序,以及函数库(若新建)或函数库升级包(若已存在)。
下面结合附图1中多层应用程序的编译流程以及图2中具体的异构多核处理器与多层应用程序对本发明做进一步的详细说明。
本发明中所述的编译方法可进行应用的一种异构多核处理器平台如图2左半部分所示,该异构多核处理器包含三种类型的处理器核,其中,R处理器称为控制处理单元,负责控制逻辑功能及一般的标量计算;S处理器称为标量处理单元,主要完成大部分的标量计算;M处理器称为微码处理单元,主要完成全部的向量计算。每一种类型的处理器均有独立的指令集体系结构,每一种类型的处理器也各有独立的编译器。在本实例中,异构多核处理器分别由1个R处理器、1个S处理器和1个M处理器所组成。同样,对于多个相同类型的处理核情况,本发明中所述的编译方法也同样适用。
该异构多核处理器支持多种不同指令集,但在该处理器平台下进行应用程序开发时,可以支持程序员在一个程序文件中完成对不同处理器核的编程工作,利用本发明所述的编译方法,程序员仅需要按照一定的程序书写要求编写满足应用需求的源程序,然后工具链可以自动完成着色、分解、预编译、关系数据库生成、调度代码与参数插入生成、后编译和程序发布等本发明所述的编译流程,从而减少程序员工作量,降低工作难度,提升异构多核处理器下的开发效率。为进一步具体说明编译流程中的细节,以图2右半部分所示的程序结构为例进行说明,该异构多核程序中包含6个函数,其中A函数属于最高层的R处理器,完成主要的控制及程序启动等功能;B函数和C函数属于第二层的S处理器,完成标量计算及部分开启下层处理器程序的功能;D函数、E函数和F函数属于最底层的M处理器,完成运算量最大的向量计算等功能。同时,如图中各个函数间的箭头关系所示,A函数在运行中需要调用B函数和C函数,B函数在运行过程中需要调用D函数和E函数,C函数在运行过程中需要调用E函数和F函数。下面就这个具体的程序组成进行具体的编译过程描述。
首先,对于一个包含A、B、C、D、E、F六个函数并如图2所示组织形式的源码,需要经过如图1中S1所示的着色分解步骤,编译器首先对源码中所有的代码进行分析,将该源码进行分解,且分解的最小粒度为函数级,通过对程序或函数中的关键字进行处理,对属于相同指令集体系结构的函数进行统一着色,并将这些统一着色的函数进行分组形成与处理器层次数量一致的源代码组,同时将这些源代码组按照颜色以及颜色所对应的指令集体系结构进行排序,排序规则按异构多核处理器中不同处理器核之间的隶属层次从高到低一一对应,例如本例中会形成三个源代码组分别对应R、S、M处理器,其中与R处理器对应的源代码组包括函数A,与S处理器对应的源代码组包括函数B和函数C,与M处理器对应的源代码组包括函数D、函数E和函数F。这里需要注意的是第1层即最高层的源代码组有且只包含一个源代码。在编译器做完着色与分解后会生成三个源代码组,并启动下一个步骤。
第二,在着色与分解步骤得到的源代码组上,需要进行如图1中S2所示的预编译步骤,该步骤主要完成将不同颜色的源码发送到其对应指令集体系结构下的编译器上进行各自的编译,并得到各自相对应的二进制代码组,同时该步骤还完成源码完整性检测功能,当发现最底层的源代码组中含有未定义函数符号时,则说明整个源代码无法完整执行,会进行报错,从而提醒程序员进行修改。如果发现最底层的源代码组中不含有未定义函数符号时,则说明整个源代码是完整的,可以送往下一步的关系数据库生成步骤。在本实施例中,异构多核处理器上的编译工具会将三个源代码组分别送往处理器R、S、M所对应的编译器,并生成函数A所对应的二进制代码,生成函数B和C所对应的二进制代码组,生成函数D、E和F所对应的二进制代码组。
第三,在经过预编译步骤后,需要建立各个源代码之间的调用关系,特别是在异构多核结构下,由于不同核之间的源代码编译环境不一致,因此需要额外建立一个源代码之间的调用关系,在这里通过逐层查找的方法,自顶向下的建立函数调用关系数据库,其具体流程为在第i层二进制代码组中的每一个二进制代码查找其是否包含未定义的函数符号,如果包含,则去第i+1层二进制代码组中进行匹配查找,如果有且只有一个匹配的函数符号,则建立一个调用关系,并将该信息存储在控制流关系数据库中,其调用关系为上一层的包含未定义函数符号的二进制代码为调用者,下一层包含函数符号二进制代码为被调用者。在这里调用关系为一一对应,如果查找过程中在下一层发现有超过一个的函数定义,则说明出现重定义异构多核函数,需要报错以提醒程序员进行修改,同时,如果查找过程中在下一层没有出现未定义函数,则说明调用函数出错,也需要报错,这种情况下不会生成控制流关系数据库。对照图2中的实例来看,当对第一层的A函数进行检查时,发现其中包含有未定义的函数B和函数C,此时需要对下一层进行匹配查找,查找结束发现函数B和函数C的定义,则生成控制流关系数据库相应的条目,形如<A,B>,<A,C>,与此类似,对第二层的B函数、C函数进行未定义函数查找,发现B函数中包含未定义的D函数与E函数,C函数中发现未定义的E函数与F函数,对下一层进行匹配查找,查找结束发现函数D、E、F的定义,并生成相应条目,形如<B,D>,<B,E>,<C,E>,<C,F>,在本层查找完成后,到达查找终止条件,该步骤结束。
第四,在控制流关系数据库生成步骤之后,需要对二进制代码组中的每个二进制代码生成相应的调度代码,同前一步骤一样,需要对除最底层之外的二进制代码组中的每一个二进制代码进行未定义函数符号检查,如果在第i层中存在未定义的函数符号x,则需要生成该函数的定义,这里的定义是指装载、启动在第i+1层中的该函数对应的二进制代码y,以及等待第i+1层中二进制代码y执行完成的阻塞等待信息,通常此信息只在串行执行方式下产生。将这些产生的信息加入到第i层的二进制源代码中即可完成调度代码的生成。例如,在第一层的A函数中生成调度B函数与C函数的装载启动信息,如果B函数与C函数在执行完成前还需要执行其他函数,此时还需要生成阻塞等待信息,并连同装载启动信息一同加入到函数A的二进制代码中。
第五,对于第四步中生成调度代码步骤中,需要检查每个源代码中的函数是否带有参数,对于无参数类型的函数,则在生成调度代码之后即可跳到下一步骤中,对于带有参数的函数,需要进行额外的处理,针对第i层的二进制代码x中包含的函数符号,在其启动第i+1层中对应的二进制代码y时插入参数拷贝代码,从而生成第i+1层的参数准备代码,与此同时,在第i+1层包含同样函数定义的二进制代码y中插入生成的参数准备代码。例如,在A函数中检测到的未定义的B函数为带参数函数,则需要在该步骤中生成参数拷贝代码并插入到A函数中相应的函数定义,同时,也需要在下一层的B函数中插入相应的参数准备代码。
第六,在经过控制流关系数据库生成、函数调度代码生成、参数传递代码生成之后,还需经过一次完整的后编译步骤,这一步骤中将各个源代码组分别用其对应的指令集体系结构编译器进行再编译,用以检查并生成整个异构多核程序的可执行程序,如果任何一个层次的编译器报错则返回错误给程序员,如果通过,则输出全部层次的二进制代码组,然后进入程序发布步骤。
最后,经过后编译步骤后需要完成程序发布,这里需要特别指出的是最后一步要从控制流关系数据库中导出该异构多核程序中所有调用关系表,这些关系表需要与最顶层的二进制代码组进行组合并封装成一个独立的可执行程序,而其他层次的二进制代码组则分别加入到其对应层次的函数库中,供可执行程序在运行时调用。
以上所述的具体实施例,对本发明的目的、技术方案和有益效果进行了进一步详细说明,应理解的是,以上所述仅为本发明的具体实施例而已,并不用于限制本发明,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。