CN115964048A - 一种gpu编译器优化方法 - Google Patents
一种gpu编译器优化方法 Download PDFInfo
- Publication number
- CN115964048A CN115964048A CN202211563572.1A CN202211563572A CN115964048A CN 115964048 A CN115964048 A CN 115964048A CN 202211563572 A CN202211563572 A CN 202211563572A CN 115964048 A CN115964048 A CN 115964048A
- Authority
- CN
- China
- Prior art keywords
- instruction
- temporary
- variable
- fma
- constant
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本发明涉及计算机技术领域,提供了一种GPU编译器优化方法,其中所述方法包括:遍历各函数中的基本块,遍历基本块中的指令,找到FMA指令;将FMA指令及FMA指令前后的几条指令一同作为模板匹配窗口;根据各指令的依赖关系,以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各优化模板对所述第一窗口进行匹配,并根据所述优化模板所对应的规则,对第一窗口中的各指令进行优化,以消除临时指令。本发明设计了多个优化模板,使编译器可以识别隐式的公共子表达式和可以化简的FMA表达式,并通过对应的规则进行优化,删除临时指令,从而减少冗余的计算,使生成的汇编代码尽可能精简,并减少冗余的资源占用,最终提高程序的执行效率。
Description
技术领域
本发明涉及计算机技术领域,特别是涉及一种GPU编译器优化方法。
背景技术
FMA(Fused Multiply Add,融合乘加)是CPU和GPU中最常见的运算操作符之一。实际应用程序中包含了大量的这类操作,并且这些操作往往前后依赖,很难在处理器中并行执行。主流的编译器如GCC编译器(GNU Compiler Collection,GNU编译器套件)、LLVM编译器、JVM编译器(Java Virtual Machine,Java虚拟机)等在优化阶段都是针对乘法和加法表达式进行诸如公共子表达式删除、表达式化简、代码增强、冗余删除等类型的优化,而没有考虑单独对FMA相关指令进行化简优化。因为并不是所有的后端处理器都支持FMA指令,所以编译器中端的相关优化很少考虑FMA指令。
此外,后端编译优化中也缺少单独针对乘加表达式的优化,例如表达式常数化简。这也会导致很多冗余的指令没有被消除。而在GPU中,FMA是使用最多的指令之一。大量的FMA冗余会限制处理器的执行速度。
鉴于此,克服该现有技术所存在的缺陷是本技术领域亟待解决的问题。
发明内容
本发明要解决的技术问题是现有的编译优化技术没有对FMA相关指令序列进行进一步的表达式化简和表达式删除等优化,导致最终生成的指令中仍存在大量冗余。
本发明采用如下技术方案:
第一方面,本发明提供了一种GPU编译器优化方法,包括:
遍历程序中各函数的基本块,遍历基本块中的指令,找到FMA指令;
如果FMA指令所在的基本块中的指令数小于等于预设值,则将基本块中全部的指令作为模板匹配窗口;否则,将所述FMA指令、FMA指令的前一条指令和FMA指令的后两条指令一同作为模板匹配窗口;
根据所述模板匹配窗口中各指令的依赖关系,检查所述模板匹配窗口中是否存在至少一条临时指令;其中,所述临时指令为未被所述模板匹配窗口外的任意一条指令所依赖的指令;
以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化;
其中,每个优化模板均至少包含临时指令和第一指令,所述第一指令依赖于所述临时指令;每个优化模板所对应的优化规则均将第一指令中的临时变量使用其他参数替代,并删除所述临时指令。
优选的,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,具体包括:
若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为ADD指令,则执行以下过程:
若所述第二FMA指令中的一个乘变量作为第一变量参与临时指令中的加运算,另一个乘变量与临时变量一同参与第一FMA指令中的乘运算,且所述第一FMA指令中的加变量与所述第二FMA指令中的加变量相同;
则将所述第一FMA指令中的临时变量替换为第二变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量,所述第二变量为所述临时指令中的另一个加变量。
优选的,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,还包括:
若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为FMA指令,则执行以下过程:
若所述第二FMA指令中的两个乘变量与第一FMA指令中的两个乘变量相同,所述第一FMA指令中的加变量为临时变量,且所述临时变量中的加变量与第二FMA指令中的加变量相同;
则将所述第一FMA指令中的两个乘变量替换为所述临时指令中的两个乘变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量。
优选的,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,还包括:
若在第一窗口的第一MUL指令前,存在临时指令和第二MUL指令,且所述临时指令为FMA指令,则执行以下过程:
若所述第二MUL指令的一个乘变量作为第一变量与第二变量一同参与临时指令中的乘运算,另一个乘变量作为第三变量与临时变量一同参与第一MUL指令中的乘运算,且所述临时指令中的加变量为1或第一变量;
则将所述第一MUL指令变更为第一FMA指令,使用第二MUL指令的结果变量和第二变量作为所述第一FMA指令的两个乘变量;
当所述临时指令中的加参数为1时,使用第三变量作为所述第一FMA指令的加变量;当所述临时指令中的加参数为第一变量时,则使用第二MUL指令的结果变量作为述第一FMA指令的加变量,并删除所述临时指令。
第二方面,本发明还提供了一种GPU编译器优化方法,使用第一方面所述的GPU编译器优化方法进行编译器优化,且还对所述第一窗口中包含有常量参数的指令进行优化。
优选的,所述对所述第一窗口中包含有常量参数的指令进行优化,具体包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量和第三常量参与乘运算的第一MUL指令时,
将所述第一MUL指令变更为第一FMA指令,以第一数值与临时指令中的乘变量一同参与第一FMA指令中的乘运算,以第二数值参与第一FMA指令中的加运算,并删除所述临时指令;其中,第一数值为第一常量与第三常量的乘积,第二数值为第二常量与第三常量的乘积。
优选的,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一ADD指令时,则执行以下过程:
若在所述第一ADD指令中,所述临时变量与第三常量一同参与加运算,则将所述第一ADD指令变更为第一FMA指令,所述第一FMA指令使用所述临时指令中的第一常量与第一变量一同参与乘运算,使用第一数值参与加运算,删除所述临时指令;其中,所述第一数值为第二常量与第三常量的和;
若在所述第一ADD指令中,所述临时变量与第一变量一同参与加运算,则将所述第一ADD指令变更为第二FMA指令,所述第二FMA指令使用第二数值和所述临时指令中的第一变量一同参与乘运算,使用所述临时指令中的第二变量参与加运算,删除所述临时指令;其中,所述第二数值为所述第一常量加1所得的值。
优选的,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一FMA指令时,
若在所述第一FMA指令中,第三常量与临时变量一同参与乘运算,第四常量参与加运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和所述第一变量,将所述第一FMA指令中的加参数替换为第二数值,删除所述临时指令;其中,所述第一数值为第一常量与第三常量的乘积,所述第二数值为第二常量与第三常量的乘积再加上第四常量所得的总和;
若在所述临时指令后,存在一条使用临时变量参与乘运算的第二FMA指令时,且在所述第二FMA指令中,第三常量与第一变量一同参与乘运算,临时变量参与加运算,则将所述第二FMA指令中的第二常量替换为第三数值,将所述第二FMA指令中的加参数替换为第二常量,删除所述临时指令;其中,所述第三数值为第一常量与第二常量的和。
优选的,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若在第一窗口的第一FMA指令中,使用临时变量和第一常量参与乘运算,使用第二常量参与加运算,且所述临时变量所对应的临时命令为MUL命令或ADD命令时,
若所述临时命令为MUL命令,且在所述临时命令中,使用第三常量和第一变量参与乘运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和第一变量,删除所述临时指令;其中,所述第一数值为第三常量与第一常量的乘积;
若所述临时命令为ADD命令,且在所述临时命令中,使用第三常量和第一变量参与加运算,则将所述第一FMA指令中的临时变量替换为第一变量,并将所述第一FMA指令中的第二常量替换为第二数值,删除所述临时指令;其中,所述第二数值为第一常量与第三常量的乘积再加上第二常量的总和。
优选的,所述模板匹配优化还进行了扩展,包括:
在执行FMA指令模板匹配优化之前,检查基本块中的指令是否包含除法操作,如果是,则将第二个操作数变成其倒数,将除法变成乘法操作。之后就能和已定义的乘加指令模板进行匹配;
还进一步扩展上述指令模板,将指令模板中的加号相应的替换为减号,增加模板数量,扩大模板匹配和优化的范围;
执行前述模板匹配优化之后,对于一些不支持FMA指令的CPU、DSP、ASIC等处理器后端,将优化后的FMA指令进一步转换成一条乘法指令和一条加法指令。
本发明通过设置优化模板,使对FMA指令进行识别,并通过对应的优化规则进行优化,以将临时指令删除,从而去除冗余的指令,对汇编代码进行优化,以减少程序运行所需的时间,并减少部分冗余的资源占用。
本发明所提供的上述各优选的方法在实际实现中具体包括下述步骤:
1.读取待编译的程序,经过预处理之后进行词法、语法、语义分析,转换成抽象语法树中间表示并进行中端优化,转换成后端中间表示,进行后端相关的优化;在后端优化中,遍历程序中的所有函数,遍历函数中的所有基本块,遍历基本块中的所有指令,找到FMA指令;
2.如果FMA指令所在的基本块中的指令数小于等于4,则将基本块中全部的指令作为模板匹配窗口;否则,将所述的FMA指令、FMA指令的前一条指令和FMA指令的后两条指令一同作为模板匹配窗口;
3.根据所述模板匹配窗口中各指令的依赖关系,检查所述模板匹配窗口中是否存在至少一条临时指令;其中,所述临时指令为未被所述模板匹配窗口外的任意一条指令所依赖的指令;
4.以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化;其中,每个优化模板均至少包含临时指令和第一指令,所述第一指令依赖于所述临时指令;每个优化模板所对应的优化规则均将第一指令中的临时变量使用其他参数替代,并删除所述临时指令。
5.FMA指令优化结束,更新指令列表,更新指令依赖关系图和寄存器列表;继续其他的后端优化。
其中,FMA指令优化的目标是减少指令数量而不影响程序的语义。
本发明设计了16个FMA指令优化模板和优化规则:
为了便于描述,这里以最简洁的表达式形式来表示指令。例如,下面的每个表达式都可以由一条指令来等价地表示,消除了表达式也就减少了相应的指令。
w=x×y+z 可表示为fma w,x,y,z
w=x+y 可表示为add w,x,y
w=x×y 可表示为mul w,x,y
在本发明所述的表达式中,x、y、z、k、w、r、d表示变量,temp表示临时变量,A、B、C、D表示常量。
本发明设计的指令优化模板分为2类,共16个:
第一类为基于公共子表达式删除的优化模板,以下7个指令模板均包含了隐式的公共子表达式:
pattern 1:
1)w=x×y+z;2)temp=x+k;3)r=y×temp+z
其中,r=x×y+z+y×k,所以x*y+z是一个公共子表达式,表达式可以优化为:
1)w=x×y+z;2)r=y×k+w
pattern 2:
1)w=x×y+z;2)temp=y+z;3)r=x×temp+z
其中,r=x×y+z+x×z,所以x×y+z是一个公共子表达式,表达式可以优化为:
1)w=x×y+z;2)r=x×z+w
pattern 3:
1)w=x×y+z;2)temp=d×k+z;3)r=x×y+temp
其中,r=x×y+z+d×k,所以x×y+z是一个公共子表达式,表达式可以优化为:
1)w=x×y+z;2)r=d×k+w
pattern 4:
1)w=x×y;2)temp=x×z+x;3)r=y×temp
其中,r=x×y×z+x×y,所以x×y是一个公共子表达式,表达式可以优化为:
1)w=x×y;2)r=z×w+w
pattern 5:
1)w=x×y;2)temp=x×z+1;3)r=y×temp
其中,r=x×y×z+y,所以x×y是一个公共子表达式,表达式可以优化为:
1)w=x×y;2)r=z×w+y
pattern 6:
1)w=x×y;2)temp=x×x+1;3)r=y×temp
其中,r=x×y×x+y,所以x×y是一个公共子表达式,表达式可以优化为:
1)w=x×y;2)r=x×w+y
pattern 7:
1)w=x×y;2)temp=x×x+x;3)r=y×temp
其中,r=x×y×x+x×y,所以x×y是一个公共子表达式,表达式可以优化为:
1)w=x×y;2)r=x×w+w
第二类为基于表达式化简的优化模板,以下9个指令模板均隐含了可以进行常数化简的表达式。
pattern 8:
1)temp=A×x+B;2)y=C×temp
这两个表达式都含有变量,目前的编译器都会对应地产生两条指令。而A、B和C是立即数常量,它们的值在编译时已知,A×C、B×C的值可以由编译器在编译时计算出来,直接存放到寄存器中,而不需要目标处理器再计算。因此表达式可以优化为一条指令:
1)y=AC×x+BC
pattern 9:
1)temp=A×x+B;2)y=temp+C
同理,表达式可以优化为:
1)y=A×x+(B+C)
pattern 10:
1)temp=A×x+B;2)y=temp+x
同理,表达式可以优化为:
1)y=(A+1)×x+B
pattern 11:
1)temp=A×x+B;2)y=C×temp+D
同理,表达式可以优化为:
1)y=AC×x+(BC+D)
pattern 12:
1)temp=A×x+B;2)y=C×x+temp
同理,表达式可以优化为:
1)y=(A+C)×x+B
pattern 13:
1)temp=A×x;2)y=B×temp+C
同理,表达式可以优化为:
1)y=AB×x+C
pattern 14:
1)temp=x+A;2)y=B×temp+C
同理,表达式可以优化为:
1)y=B×x+(AB+C)
pattern 15:
1)temp=A×x;2)y=B×x+temp
同理,表达式可以优化为:
1)y=(A+B)×x
pattern 16:
1)temp=x+A;2)y=B×x+temp
同理,表达式可以优化为:
1)y=(B+1)×x+A
如果编译器检查到程序中的指令和上述16个模板之一相匹配,就会进行FMA指令优化,从而减少一条乘加、乘法或者加法指令。
值得说明的是,本发明并不局限于上述16个模板。实际上,根据本发明提供的优化思路,可以很容易地得到更多的优化模板。这里不再举例赘述。
本发明还提供了一种上述编译优化方法的扩展,使其不局限于仅针对乘加指令序列的优化,也不局限于GPU处理器,所述方法包括:
1.在执行FMA指令模板匹配优化之前,检查基本块中的指令是否包含除法操作,如果是,则将第二个操作数变成其倒数,将除法变成乘法操作。例如w=x÷y变成d=1÷y;w=x×d。之后就能和已定义的乘加指令模板进行匹配。
2.扩展上述指令模板,将指令模板中的加号相应的替换为减号,增加模板数量,扩大模板匹配和优化的范围。
3.执行前述模板匹配优化。
4.对于一些不支持FMA指令的CPU、DSP、ASIC等处理器后端,将优化后的FMA指令进一步转换成一条乘法指令和一条加法指令,整体的指令数仍然是减少的。
本发明设计了多个指令优化模板,通过相应的优化规则,删除了代码中隐含的冗余指令,使生成的汇编指令尽可能精简,并减少冗余的资源占用,减少可执行程序运行的时间。
附图说明
为了更清楚地说明本发明实施例的技术方案,下面将对本发明实施例中所需要使用的附图作简单地介绍。显而易见地,下面所描述的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图2是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图3是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图4是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图5是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图6是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图7是本发明实施例提供的一种GPU编译器优化方法的示意图;
图8是本发明实施例提供的一种GPU编译器优化方法的流程示意图;
图9是本发明实施例提供的一种GPU编译器优化方法的流程示意图。
具体实施方式
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
在此需要说明的是,本实施例中的“第一”、“第二”等限定性描述并非代指某一具体的对象,也并非是指代特定顺序含义,仅仅是为了让对应限定的对象能够从同类中脱离出来,并且是为了方便描述同类中不同的两个对象或者多个对象方便而加的限定,不应该将其解释出进一步限定意义。且在本实施例中,由于存在多个优化模板,每个模板均涉及多个变量,为了描述的便利性,所述“第一”、“第二”等限定性描述均是相对于单个模板所言的,在不同的模板中,可能均使用到同一命名,如在第一模板和第二模板中均出现了“第一变量”,此时应当理解为不同的对象,不应将其理解为同一描述对象。
FMA是CPU和GPU中最常见的运算操作符之一,在实际测试中发现,这一类的指令序列往往还有进一步的优化空间。
例如,当存在三个连续的表达式:1)w=x×y;2)temp=x×z+x;3)r=y×temp,且temp是临时变量只在表达式3)中被使用时,表达式可以优化为1)w=x×y2)r=w×z+w。其中,x×y是隐式的公共子表达式。但现有的优化技术无法识别该公共子表达式,也就不会执行上述优化。经实际测试,GCC、LLVM和JVM编译器在使用最高的优化选项时,依旧无法对这类表达式进行优化。生成的X86汇编代码仍包含三条乘法指令,而临时指令所对应的第二条乘法指令是冗余的。
目前,主流的编译器所优化的表达式均是相对明显和易替换的,它们仅针对显式的公共子表达式进行优化。例如将上述连续的表达式稍微改动,变成4)w=x×y;5)temp=x×y+x;6)r=y×temp时,由于4)和5)中具有显式的公共子表达式x×y,现有的编译优化技术能够将这三条指令优化为两条指令:1)w=x×y;2)r=w×y+w,生成的X86汇编代码只包含两条乘法指令,即只有在两个表达式中存在完全相同的子式时才会进行优化。这种优化方式具有一定的局限性,最终生成的可执行程序可能还存在着大量冗余。
还需要强调的是,本实施例中多次涉及“常量”““变量”““参数”等描述,此均为本领域技术人员惯用称谓,其中,凡是参与相应指令中的运算的均称为参数,将数值已确定的参数称为常量,将数值取决于某一运算过程的运算结果,即可能发生改变的参数称为变量,举例而言,存在一条FMA指令使用中间表示的指令表示为fma w,x,y,3,其转化为数学表达式为w=x×y+3,其中,w、x、y和3均为该条指令的参数,x和y的值由该条指令之前的某条指令计算得到,即x和y为变量,w的值取决于该指令的运算结果,w也为变量,而3为常量。
而在不同类型的指令中,为了区分不同的变量或参数,以加”、乘”、结果”等作为参数或变量的前缀进行区别描述,举例而言,在ADD指令中仅包含加运算,其中涉及一个结果参数和两个加参数,当其中的一个加参数为变量时,还可描述为加变量,在FMA指令中包括一次乘运算和一次加运算,涉及一个结果参数、两个乘参数和一个加参数,同样的,当乘参数为变量时,还可称为乘变量,当加参数为变量时,还可称为加变量,其中,由于指令中的结果参数均为变量,故在实施例中称作结果变量。
此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。
本发明实施例提供了一种GPU编译器优化方法,如图1所示,包括:
在步骤201中,遍历程序中的所有函数,遍历函数中的基本块,遍历基本块中的所有指令,找到FMA指令。
在步骤202中,如果FMA指令所在的基本块中的指令数小于等于预设值,则将基本块中全部的指令作为模板匹配窗口,在本发明实施例中,以所述预设值等于4为例;否则,将所述FMA指令、FMA指令的前一条指令和FMA指令的后两条指令一同作为模板匹配窗口。
在步骤203中,根据所述模板匹配窗口中各指令的依赖关系,检查所述模板匹配窗口中是否存在至少一条临时指令;其中,所述临时指令为未被所述模板匹配窗口外的任意一条指令所依赖的指令。
在步骤204中,以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化;其中,每个优化模板均至少包含临时指令和第一指令,所述第一指令依赖于所述临时指令;每个优化模板所对应的优化规则均将第一指令中的临时变量使用其他参数替代,并删除所述临时指令。
所述将第一指令中的临时变量使用其他参数替代需根据具体的优化规则来决定,其通常为使用临时指令和其他指令中的相应参数进行替换。在一些情况下,还可能对第一指令的指令类型进行变更。
在后续实施例中,所述临时指令的结果变量被称为临时变量。
本实施例通过设置优化模板和相应的优化规则,来删除临时指令,从而去掉冗余的计算,优化汇编代码。所述优化的目的主要是减少指令数量而不影响程序的语义,以减少程序运行所需的时间,并减少部分冗余的资源占用。
在实际使用中,对FMA指令的优化具有多种情况,每种情况可能对应不同的优化规则,故存在多个优化模板,作为一种可选的实施方式,本实施例在此提供16个可选的优化模板对FMA指令优化的情况做具体匹配和优化,下面将就各优化模板即对应的优化规则进行具体的描述。
在使用优化模板一和优化模板二进行匹配时,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,如图2所示,具体包括:
在步骤301中,若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为ADD指令,则执行以下过程:
在步骤302中,若所述第二FMA指令中的一个乘变量作为第一变量参与临时指令中的加运算,另一个乘变量与临时变量一同参与第一FMA指令中的乘运算,且所述第一FMA指令中的加变量与所述第二FMA指令中的加变量相同。
在步骤303中,则将所述第一FMA指令中的临时变量替换为第二变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量,所述第二变量为所述临时指令中的另一个加变量(即所述临时指令中的两个加变量分别为所述第一变量和第二变量)。
所述优化模板一以数学公式的形式可表现为:
第二FMA指令:w=x×y+z。
临时指令:temp=x+k。
第一FMA指令:r=y×temp+z。
其中,x为第一变量,k为第二变量,直观来看,第一FMA指令与第二FMA指令中未包含有显式的公共子表达式,而将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:r=y×(x+k)+z=(x×y+z)+y×k,可以看到,第一FMA指令与第二FMA指令中包含有隐式的公共子表达式x×y+z,而现有技术无法对该隐式的公共子表达式进行优化。
本实施例则通过将第一FMA指令中的临时变量temp替换为第二变量k,将第一FMA指令中的加变量z替换为第二FMA指令的结果变量w,使第一FMA指令无需依赖于临时指令,进而将临时指令删除,将上述三条指令优化为以下两条FMA指令:
第二FMA指令:w=x×y+z。
第一FMA指令:r=y×k+w。
需要说明的是,上述每一条数学公式均代指相应的中间表示指令,举例而言,r=y×k+w所代指的指令为fma r,y,k,w。在此仅仅是为了便于直观表现各指令中的运算关系,而采用数学公式的方式进行表示,在实际使用中,实际是对各个指令进行匹配和优化。
还存在以优化模板一衍生得到的模板二以及对应的优化规则:
第二FMA指令:w=x×y+z。
临时指令:temp=y+z。
第一FMA指令:r=x×temp+z。
其最终优化得到:
第二FMA指令:w=x×y+z。
第一FMA指令:r=x×z+w。
在使用优化模板三进行匹配时,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,如图3所示,还包括:
在步骤401中,若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为FMA指令,则执行以下过程:
在步骤402中,若所述第二FMA指令中的两个乘变量与第一FMA指令中的两个乘变量相同,所述第一FMA指令中的加变量为临时变量,且所述临时变量中的加变量与第二FMA指令中的加变量相同。
在步骤403中,则将所述第一FMA指令中的两个乘变量替换为所述临时指令中的两个乘变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量。
所述优化模板三以数学公式的形式可表现为:
第二FMA指令:w=x×y+z。
临时指令:temp=k1×k2+z。
第一FMA指令:r=x×y+temp。
其中,直观来看,第一FMA指令与第二FMA指令中未包含显式的公共子表达式,而将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:r=x×y+(k1×k2+z=x×y+z+k1×k2,可以看到,第一FMA指令与第二FMA指令中包含有隐式的公共子表达式x×y+z,而现有技术无法对该隐式的公共子表达式进行优化。
本实施例则通过将第一FMA指令中的两个乘变量(即x和y)替换为所述临时指令中的两个乘变量(即k1和k2),将第一FMA指令中的加变量temp替换为第二FMA指令的结果变量w,使第一FMA指令无需依赖于临时指令,进而将临时指令删除,将上述三条指令优化为以下两条FMA指令:
第二FMA指令:w=x×y+z。
第一FMA指令:r=k1×k2+w。
在使用模板四、模板五、模板六和模板七进行匹配时,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,如图4所示,还包括:
在步骤501中,若在第一窗口的第一MUL指令前,存在临时指令和第二MUL指令,且所述临时指令为FMA指令,则执行以下过程:
在步骤502中,若所述第二MUL指令的一个乘变量作为第一变量与第二变量一同参与临时指令中的乘运算,另一个乘变量作为第三变量与临时变量一同参与第一MUL指令中的乘运算,且所述临时指令中的加变量为1或第一变量。
在步骤503中,则将所述第一MUL指令变更为第一FMA指令,使用第二MUL指令的结果变量和第二变量作为所述第一FMA指令的两个乘变量。
在步骤504中,当所述临时指令中的加参数为1时,使用第三变量作为所述第一FMA指令的加变量;当所述临时指令中的加参数为第一变量时,则使用第二MUL指令的结果变量作为述第一FMA指令的加变量,并删除所述临时指令。
所述优化模板四以数学公式的形式可表现为:
第二MUL指令:w=x×y。
临时指令:temp=x×z+x。
第一MUL指令:r=y×temp。
其中,x为第一变量,z为第二变量,y为第三变量,直观来看,第一FMA指令与第二FMA指令中未包含有显式的公共子表达式,而将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:r=y×(x×z+x)=(x×y)×z+x×y,可以看到,第一FMA指令与第二FMA指令中包含有隐式的公共子表达式x×y,而现有技术无法对该隐式的公共子表达式进行优化。
本实施例则通过将第一MUL指令变更为第一FMA指令,使用第二MUL指令的结果变量w和第二变量z作为所述第一FMA指令的两个乘变量,且由于所述临时指令中的加参数为第一变量x,则按照优化规则,使用第二MUL指令的结果变量w和第二变量z作为所述第一FMA指令的两个乘变量,并使用第二MUL指令的结果变量w作为述第一FMA指令的加变量,并将临时指令删除,将上述三条指令优化为以下两条FMA指令:
第二FMA指令:w=x×y。
第一FMA指令:r=z×w+w。
而当所述临时指令中的加参数为1时,存在优化模板五,以数学公式的形式可表现为:
第二MUL指令:w=x×y。
临时指令:temp=x×z+1。
第一MUL指令:r=y×temp。
其中,x为第一变量,z为第二变量,y为第三变量,直观来看,第一FMA指令与第二FMA指令中未包含有显式的公共子表达式,而将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:r=y×(x×z+1)=(x×y)×z+y,可以看到,第一FMA指令与第二FMA指令中包含有隐式的公共子表达式x×y,而现有技术无法对该隐式的公共子表达式进行优化。
本实施例则通过将第一MUL指令变更为第一FMA指令,使用第二MUL指令的结果变量w和第二变量z作为所述第一FMA指令的两个乘变量,且由于所述临时指令中的加参数为1,则按照优化规则,使用第二MUL指令的结果变量w和第二变量z作为所述第一FMA指令的两个乘变量,并使用第二MUL指令的第三变量y作为述第一FMA指令的加变量,并将临时指令删除,将上述三条指令优化为以下两条FMA指令:
第二FMA指令:w=x×y。
第一FMA指令:r=z×w+y。
在优化模板五的基础上,进行衍生得到优化模板六和对应的优化规则为:
第二MUL指令:w=x×y。
临时指令:temp=x×x+1。
第一MUL指令:r=y×temp。
其最终优化得到:
第二FMA指令:w=x×y。
第一FMA指令:r=x×w+y。
在优化模板四的基础上,进行衍生得到优化模板七和对应的优化规则为:
第二MUL指令:w=x×y。
临时指令:temp=x×x+x。
第一MUL指令:r=y×temp。
其最终优化得到:
第二FMA指令:w=x×y。
第一FMA指令:r=x×w+w。
在实际使用中,指令的运算中还存在一类SUB指令,当SUB指令与FMA指令相关时,也可能存在指令冗余,举例而言,存在以下三条指令:
第二FMA指令:w=x×y+z。
临时指令:temp=y-k。
第一FMA指令:r=x×temp+z。
其中,临时指令为SUB指令,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:r=x×(y-k)+z=(x×y+z)-k×x,可以看到,第一FMA指令与第二FMA指令中包含有隐式的公共子表达式x×y+z,即存在指令冗余,针对此问题,本实施例还提供了以下优选的实施方式,具体包括:
所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化,如图5所示,还包括:
在步骤601中,当所述第一窗口中出现SUB命令时,将所述SUB命令转换为ADD命令,以ADD命令参与优化模板匹配。所述将所述SUB命令转换为ADD命令具体为,将SUB命令中的减参数转换为对应的负值的加参数,以将减运算转换为加运算,从而转换得到ADD命令。
在步骤602中,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化。
如针对上述临时指令temp=y-k,可将其视作y与-k两个参数的加法运算,从而转换为ADD指令参与优化模板匹配,上述三条指令与模板二相匹配,则按照对应的优化规则进行优化,最终优化得到:
第二FMA指令:w=x×y+z。
第一FMA指令:r=-k×x+w。
从而去除冗余的临时指令。
在实际使用中,编译器需要先将待编译的程序做一些转换,才能进行模板匹配优化,在此融合上述实施方式,提供了以下完整的实施步骤:
1)读取待编译的程序,经过预处理之后进行词法、语法、语义分析,转换成抽象语法树中间表示并进行前期的优化,转换成后端中间表示,进行后端相关的优化。
2)在后端优化中,遍历程序中的所有函数,遍历函数中的所有基本块,遍历基本块中的所有FMA指令,检查FMA及其前后的指令是否匹配已定义的指令模板(即各优化模板)。
3)如果和指令模板相匹配,则将已匹配的几条指令按照对应的优化规则替换为指令模板优化后的指令;否则,继续遍历下一条指令。
4)FMA指令优化结束,更新指令列表,更新指令依赖关系和寄存器列表。
5)继续其他的后端优化,最后生成汇编代码并编码成可执行文件进行输出。
在实际使用中,不仅仅公共子表达式可能导致指令的冗余,当临时指令或依赖于临时指令的指令中存在常量的参与时,也可能存在指令冗余的问题,为了解决此问题,本发明实施例还提供了一种GPU编译器优化方法。
所述GPU编译器优化方法使用如上实施例所述的GPU编译器优化方法进行编译器优化的同时,还对所述第一窗口中包含有常量参数的指令进行优化。
所述对所述第一窗口中包含有常量参数的指令进行优化,具体包括:
以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各化简模板对所述第一窗口进行匹配,若所述第一窗口与相应的化简模板匹配成功,则根据所述化简模板所对应的化简规则,对所述第一窗口中的各指令进行优化。
本实施例还提供了9种化简模板进行匹配化简,下面将对这些化简模板和对应的化简规则进行具体阐述。
在使用化简模板一进行匹配时,所述对所述第一窗口中包含有常量参数的指令进行优化,如图6所示,具体包括:
在步骤701中,若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量和第三常量参与乘运算的第一MUL指令时:
在步骤702中,将所述第一MUL指令变更为第一FMA指令,以第一数值与临时指令中的乘变量一同参与第一FMA指令中的乘运算,以第二数值参与第一FMA指令中的加运算,并删除所述临时指令;其中,第一数值为第一常量与第三常量的乘积,第二数值为第二常量与第三常量的乘积。
所述化简模板一以数学公式的形式可表现为:
临时指令:temp=A×x+B。
第一MUL指令:y=C×temp。
其中,A为第一常量,B为第二常量,C为第三常量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=C×(A×x+B)=A×C×x+B×C,由于A、B和C均为常量,则A×C的值和B×C的值可在编译时由编译器提前计算出来,直接将运算结果存放到寄存器中,故可对其进行优化。
将第一MUL指令变更为第一FMA指令,以第一数值(即A×C)与临时指令中的乘变量一同参与第一FMA指令中的乘运算,以第二数值(即B×C)参与第一FMA指令中的加运算,并将临时指令删除,将上述两条指令优化为一条FMA指令y=AC×x+BC。
在使用化简模板二和化简模板三进行匹配时,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一ADD指令时,则执行以下过程:
若在所述第一ADD指令中,所述临时变量与第三常量一同参与加运算,则将所述第一ADD指令变更为第一FMA指令,所述第一FMA指令使用所述临时指令中的第一常量与第一变量一同参与乘运算,使用第一数值参与加运算,删除所述临时指令;其中,所述第一数值为第二常量与第三常量的和。
若在所述第一ADD指令中,所述临时变量与第一变量一同参与加运算,则将所述第一ADD指令变更为第二FMA指令,所述第二FMA指令使用第二数值和所述临时指令中的第一变量一同参与乘运算,使用所述临时指令中的第二变量参与加运算,删除所述临时指令;其中,所述第二数值为所述第一常量加1所得的值。
所述化简模板二以数学公式的形式可表现为:
临时指令:temp=A×x+B。
第一ADD指令:y=temp+C。
其中,A为第一常量,B为第二常量,C为第三常量,x为第一变量,将第一ADD指令中的临时变量temp使用临时指令进行代入并化简得到:y=(A×x+B)+C=A×x+(B+C),由于B和C均为常量,则B+C的值可在编译时由编译器提前计算出来,故可对其进行优化。
将第一ADD指令变更为第一FMA指令,使用所述临时指令中的第一常量A与第一变量x一同参与乘运算,使用第一数值(即B+C)参与加运算并将临时指令删除,将上述两条指令优化为一条第一FMA指令y=A×x+(B+C)。
所述化简模板三以数学公式的形式可表现为:
临时指令:temp=A×x+B。
第一ADD指令:y=temp+x。
其中,A为第一常量,B为第二常量,x为第一变量,将第一ADD指令中的临时变量temp使用临时指令进行代入并化简得到:y=(A×x+B)+x=(A+1)×x+B,由于A为常量,则A+1的值可在编译时由编译器提前计算出来,故可对其进行优化。
将第一ADD指令变更为第二FMA指令,使用第二数值(即A+1)和所述临时指令中的第一变量x一同参与乘运算,使用所述临时指令中的第二变量B参与加运算,并将临时指令删除,将上述两条指令优化为一条第二FMA指令y=(A+1)×x+B。
其中,在使用化简模板四和化简模板五进行匹配时,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一FMA指令时:
若在所述第一FMA指令中,第三常量与临时变量一同参与乘运算,第四常量参与加运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和所述第一变量,将所述第一FMA指令中的加参数替换为第二数值,删除所述临时指令;其中,所述第一数值为第一常量与第三常量的乘积,所述第二数值为第二常量与第三常量的乘积再加上第四常量所得的总和。
若在所述临时指令后,存在一条使用临时变量参与乘运算的第二FMA指令时,若在所述第二FMA指令中,第三常量与第一变量一同参与乘运算,临时变量参与加运算,则将所述第二FMA指令中的第二常量替换为第三数值,将所述第二FMA指令中的加参数替换为第二常量,删除所述临时指令;其中,所述第三数值为第一常量与第二常量的和。
所述化简模板四以数学公式的形式可表现为:
临时指令:temp=A×x+B。
第一FMA指令:y=C×temp+D。
其中,A为第一常量,B为第二常量,C为第三常量,D为第三常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=C×(A×x+B)+D=(A×C)×x+(B×C+D),由于A、B、C和D均为常量,则A×C的值和B×C+D的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令中的两个乘参数分别替换为第一数值和所述第一变量,将所述第一FMA指令中的加参数替换为第二数值,并将临时指令删除,将上述两条指令优化为一条第一FMA指令:y=AC×x+(BC+D)。
所述化简模板五以数学公式的形式可表现为:
临时指令:temp=A×x+B。
第一FMA指令:y=C×x+temp。
其中,A为第一常量,B为第二常量,C为第三常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=C×x+(A×x+B)=(A+C)×x+B,由于A、B、C和D均为常量,则A+C的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令中的两个乘参数分别替换为第一数值和所述第一变量,将所述第一FMA指令中的加参数替换为第二数值,并将临时指令删除,将上述两条指令优化为一条第一FMA指令:y=(A+C)×x+B。
在使用化简模板六和化简模板七进行匹配时,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若在第一窗口的第一FMA指令中,使用临时变量和第一常量参与乘运算,使用第二常量参与加运算,且所述临时变量所对应的临时命令为MUL命令或ADD命令时:
若所述临时命令为MUL命令,且在所述临时命令中,使用第三常量和第一变量参与乘运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和第一变量,删除所述临时指令;其中,所述第一数值为第三常量与第一常量的乘积。
若所述临时命令为ADD命令,且在所述临时命令中,使用第三常量和第一变量参与加运算,则将所述第一FMA指令中的临时变量替换为第一变量,并将所述第一FMA指令中的第二常量替换为第二数值,删除所述临时指令;其中,所述第二数值为第一常量与第三常量的乘积再加上第二常量的总和。
所述化简模板六以数学公式的形式可表现为:
临时指令:temp=A×x。
第一FMA指令:y=temp×B+C。
其中,B为第一常量,C为第二常量,A为第三常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=(A×x)×B+C=(A×B)×x+C,由于A和B均为常量,则A×B的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令中的两个乘参数分别替换为第一数值(即A×B)和第一变量,将第一FMA指令优化为:y=AB×x+C。
进而将临时指令删除,将上述两条指令优化为一条FMA指令,以去除指令的冗余计算,以数学公式的形式可表现为:
第一FMA指令:y=AB×x+C。
所述化简模板七以数学公式的形式可表现为:
临时指令:temp=x+A。
第一FMA指令:y=B×temp+C。
其中,B为第一常量,C为第二常量,A为第三常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=B×(x+A)+C=B×x+(A×B+C),由于A、B和C均为常量,则A×B+C的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令中的两个乘参数分别替换为第一数值(即A×B+C)和第一变量x,并将临时指令删除,将上述两条指令优化为一条第一FMA指令y=B×x+(AB+C)。
在使用化简模板八和化简模板九进行匹配时,所述对所述第一窗口中包含有常量参数的指令进行优化,还包括:
若在第一窗口的第一FMA指令中,使用第一常量和第一变量参与乘运算,使用临时变量参与加运算,且所述临时变量所对应的临时命令为MUL命令或ADD命令时:
若所述临时命令为MUL命令,且在所述临时命令中,使用第二常量和第一变量参与乘运算,则将所述第一FMA指令替换为第一MUL指令,以第一变量和第一数值分别作为所述第一MUL指令中的乘参数,删除所述临时指令;其中,所述第一数值为第一常量和第二常量的和。
当所述临时命令为ADD命令,且在所述临时命令中,使用第二常量和第一变量参与加运算,则将所述第一FMA指令中的第一常量替换为第一数值,将所述第一FMA指令中的临时变量替换为第二常量;其中,所述第一数值为所述第一常量加1所得的值,删除所述临时指令。
所述化简模板八以数学公式的形式可表现为:
临时指令:temp=A×x。
第一FMA指令:y=B×x+temp。
其中,B为第一常量,A为第二常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=B×x+(A×x)=(A+B)×x,由于A和B均为常量,则A+B的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令替换为第一MUL指令,以第一变量B和第一数值(即A+B)分别作为所述第一MUL指令中的乘参数,并将临时指令删除,将上述两条指令优化为一条第一MUL指令y=(A+B)×x。
所述化简模板九以数学公式的形式可表现为:
临时指令:temp=x+A。
第一FMA指令:y=B×x+temp。
其中,B为第一常量,A为第二常量,x为第一变量,将第一FMA指令中的临时变量temp使用临时指令进行代入并化简得到:y=B×x+(x+A)=(B+1)×x+A,由于B为常量,则B+1的值可在编译时由编译器提前计算出来,故可对其进行优化。
将所述第一FMA指令中的第一常量B替换为第一数值(即B+1),将所述第一FMA指令中的临时变量替换为第二常量A,将第一FMA指令优化为:y=(B+1)×x+A,并将临时指令删除,将上述两条指令优化为一条第一MUL指令:y=(B+1)×x+A。
如图7所示,待编译的程序经过编译器前端的预处理、词法分析、语法分析、语义分析之后生成中端的中间表示,中间表示经过中端的控制流分析、数据流分析、依赖性分析、中端优化、中间表示转换生成后端中间表示,后端中间表示经过后端优化、指令选择、指令调度、寄存器分配、代码生成、指令编码后生成目标文件。目标文件可以在GPU硬件上执行。
本发明的编译优化方法是上述编译流程中的后端优化中的一个优化过程,编译器中称为一个pass。后端中间表示经过FMA指令优化后继续传输到下一个优化pass。
下面结合图8和实施例对本发明的FMA指令优化的具体实现方法做详细的说明,具体包括:
在步骤801中,遍历程序中的所有函数;进入步骤802中,直至程序中的所有函数遍历结束,则进入步骤811。
在步骤802中,在每个函数中删除不可达的基本块、合并没有分支跳转的连续基本块;更新指令的依赖关系图;进入步骤803。
在步骤803中,遍历每个函数中的所有基本块,进入步骤804。
在步骤804中,判断是否遍历完对应函数中的所有基本块;每访问一个基本块,进入步骤805中;若函数中的基本块均遍历结束,则进入步骤801,继续访问下一个函数。
在步骤805中,遍历每个基本块中的所有FMA指令;其具体为:检查对应基本块中是否有FMA类型的指令,如果没有则继续遍历下一个基本块;若存在FMA指令,则进入步骤806。
在步骤806中,检查FMA指令中的源寄存器之一是否为变量类型(即判断FMA指令中是否存在变量,若不存在变量,则不存在对其他指令的依赖,无需进行优化),如果不是则进入步骤805中,继续遍历下一个FMA指令;否则,进入步骤807。
在步骤807中,判断当前基本块中的指令数量是否小于等于4,若小于等于4,则进入步骤808,否则,进入步骤809。
在步骤808中,如果当前基本块中的指令数小于等于4,则取出全部的指令,作为模板匹配窗口;进入步骤810。
在步骤809中,否则,取出FMA指令、FMA指令的前一条指令、FMA指令的后两条指令,这4条指令作为模板匹配窗口;进入步骤810。
在步骤810中,对模板匹配窗口进行模板匹配,以进行代码优化,之后,进入步骤805中,遍历下一条FMA指令。
在步骤811中,在所有指令遍历完之后,如果进行了FMA指令的优化,则更新指令列表,更新依赖关系图,更新寄存器列表。
在所述步骤810中,所述对模板匹配窗口进行模板匹配,以进行代码优化,如图9所示,具体包括:
在步骤901中,分别检查取出的这些指令的依赖关系图,如果指令没有被当前窗口外的其他指令所真依赖(即目标寄存器之后没有被读),则所述指令为临时指令,则将该目标寄存器的属性标记为temp。
在步骤902中,检查指令窗口中是否有temp属性的目标寄存器,如果没有则不进行代码优化,否则,进入步骤903中进行模板匹配。
在步骤903中,分别将这些指令的指令类型、源寄存器和目标寄存器按顺序与设定的16个指令模板(包括实施例1中的7个优化模板和实施例2中的9个化简模板)进行匹配。
在步骤904中,如果其中的3条指令和实施例1中所述的各优化模板中的一个匹配一致,则保留原第一条指令,删除原第二条指令,按照前述的模板规则修改原第三条指令的指令类型和源寄存器。
在步骤905中,如果其中的2条指令和实施例2中的各化简模板中的一个匹配一致,则删除原第一条指令,按照前述的各模板所对应的优化规则和化简规则计算第二条指令中源寄存器的值,并修改指令类型和源寄存器。
其中,上述步骤901至步骤905是FMA指令优化的核心,下面结合具体实施例中的一部分代码来详细说明指令模板匹配的过程。
对于下面的程序:
in float3 a[10000];
out float2 b[10000];
int i;
float temp;
for(i=0;i<10000;i++)
{
b[i].x=a[i].x*a[i].y;
temp=a[i].x*a[i].z+a[i].x;
b[i].y=temp*a[i].y;
}
循环中的表达式会产生如下中间表示的指令,其在一个基本块中:
mul r19,r1,r0;
fma r21,r2,r0,r0;
mul r22,r21,r1
按照步骤808或步骤809,取出这些指令,作为模板匹配的窗口。
按照步骤901,检查这三条指令的依赖关系图。其中,第一和第三条指令被其他基本块中的指令依赖(因为变量b会被输出),即r19和r22在后面会被读。r21不会被后续指令读,标记其属性为temp。
按照步骤902,检查到指令窗口包含了属性为temp的目标寄存器。
按照步骤903,首先检查包含temp的指令是{fma temp,r2,r0,r0},它与pattern3和pattern 4中包含temp的模板指令相匹配。然后检查temp的前一条指令是{mul r19,r1,r0},它与pattern 4中temp的前一条模板指令相匹配。最后检查temp的后一条指令是{mulr22,temp,r1},它与pattern 4中temp的后一条模板指令相匹配。输出指令窗口与pattern4匹配的标记。
按照步骤904,第一条指令不变,删除第二条指令,修改第三条指令为{fma r22,r19,r2,r19}。
对于步骤905,指令匹配的是模板8~16,由编译器计算化简后的常量系数放到寄存器中,再进行指令替换,过程与上述类似,这里不再举例赘述。
可以看到,上述程序经过FMA指令优化后,循环中的指令变成了:
mul r19,r1,r0;
fma r22,r19,r2,r19
核心循环中减少了一条乘法指令。经实际测试,优化后的代码的执行时间会减少约33%。
这种优化方法特别适合需要强渲染的GPU应用程序,例如3D游戏、影视动画、4K视频编解码、工程建模仿真等,它们的底层代码包含了大量的float类型的FMA操作。
本发明实施例还提供了一种上述编译器优化方法的扩展,使其不局限于仅针对乘加指令序列的优化,也不局限于仅针对GPU处理器,所述扩展方法包括:
1.在上述实施例的步骤805中,在执行FMA指令模板匹配优化之前,检查基本块中的指令是否包含除法操作,如果是,则将第二个操作数变成其倒数,将除法变成乘法操作。例如w=x÷y变成r=1÷y;w=x×r。之后就能和已定义的乘加指令模板进行匹配。
2.继续扩展上述指令模板,将指令模板中的加号相应的替换为减号,增加模板数量,扩大模板匹配和优化的范围,尽可能减少相关冗余指令。前述实施例中列举了一个减法的实例。
3.执行前述模板匹配优化。
4.对于一些不支持FMA指令的CPU、DSP、ASIC等处理器,将优化之后的FMA指令进一步转换成一条乘法指令和一条加法指令,整体的指令数仍然减少了。
5.继续其他的后端优化。
应当理解,这里所描述的具体实施例仅用于解释本发明,并不限定于本发明。例如本领域的普通技术人员可以很容易地依据本发明的方法进一步扩展指令模板中的优化内容,进行更多类似的优化,以扩大指令优化的适用范围,进一步提高各种类型的实际应用的执行效率。
需要说明的是,本发明的FMA指令优化的编译优化过程是编译过程中将一个中间表示优化后再次输出的过程。其可以作为一个通用的模块,增加到任何兼容的编译器中,也不局限于特定的处理器,具有非常广泛的适用性。从直观上和实际测试来看,本发明中的方法可以显著提升编译器的优化效果。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。
Claims (10)
1.一种GPU编译器优化方法,其特征在于,包括:
遍历程序中各函数的基本块,遍历基本块中的指令,找到FMA指令;
如果FMA指令所在的基本块中的指令数小于等于预设值,则将基本块中全部的指令作为模板匹配窗口;否则,将所述FMA指令、FMA指令的前一条指令和FMA指令的后两条指令一同作为模板匹配窗口;
根据所述模板匹配窗口中各指令的依赖关系,检查所述模板匹配窗口中是否存在至少一条临时指令;其中,所述临时指令为未被所述模板匹配窗口外的任意一条指令所依赖的指令;
以存在至少一条临时指令的模板匹配窗口作为第一窗口,使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化;
其中,每个优化模板均至少包含临时指令和第一指令,所述第一指令依赖于所述临时指令;每个优化模板所对应的优化规则均将第一指令中的临时变量使用其他参数替代,并删除所述临时指令。
2.根据权利要求1所述的GPU编译器优化方法,其特征在于,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化包括:
若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为ADD指令,则执行以下过程:
若所述第二FMA指令中的一个乘变量作为第一变量参与临时指令中的加运算,另一个乘变量与临时变量一同参与第一FMA指令中的乘运算,且所述第一FMA指令中的加变量与所述第二FMA指令中的加变量相同;
则将所述第一FMA指令中的临时变量替换为第二变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量,所述第二变量为所述临时指令中的另一个加变量。
3.根据权利要求1所述的GPU编译器优化方法,其特征在于,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化包括:
若在第一窗口中的第一FMA指令之前,存在临时指令和第二FMA指令,且所述临时指令为FMA指令,则执行以下过程:
若所述第二FMA指令中的两个乘变量与第一FMA指令中的两个乘变量相同,所述第一FMA指令中的加变量为临时变量,且所述临时变量中的加变量与第二FMA指令中的加变量相同;
则将所述第一FMA指令中的两个乘变量替换为所述临时指令中的两个乘变量,将所述第一FMA指令中的加变量替换为所述第二FMA指令的结果变量,并删除所述临时指令;其中,所述临时变量为所述临时指令的结果变量。
4.根据权利要求1所述的GPU编译器优化方法,其特征在于,所述使用各优化模板对所述第一窗口进行匹配,若所述第一窗口与相应的优化模板匹配成功,则根据所述优化模板所对应的优化规则,对所述第一窗口中的各指令进行优化包括:
若在第一窗口的第一MUL指令前,存在临时指令和第二MUL指令,且所述临时指令为FMA指令,则执行以下过程:
若所述第二MUL指令的一个乘变量作为第一变量与第二变量一同参与临时指令中的乘运算,另一个乘变量作为第三变量与临时变量一同参与第一MUL指令中的乘运算,且所述临时指令中的加变量为1或第一变量;
则将所述第一MUL指令变更为第一FMA指令,使用第二MUL指令的结果变量和第二变量作为所述第一FMA指令的两个乘变量;
当所述临时指令中的加参数为1时,使用第三变量作为所述第一FMA指令的加变量;当所述临时指令中的加参数为第一变量时,则使用第二MUL指令的结果变量作为述第一FMA指令的加变量,并删除所述临时指令。
5.一种GPU编译器优化方法,其特征在于,使用权利要求1至4中任一项所述的GPU编译器优化方法进行编译器优化,且对第一窗口中包含有常量参数的指令进行优化。
6.根据权利要求5所述的GPU编译器优化方法,其特征在于,所述对第一窗口中包含有常量参数的指令进行优化包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量和第三常量参与乘运算的第一MUL指令时,
将所述第一MUL指令变更为第一FMA指令,以第一数值与临时指令中的乘变量一同参与第一FMA指令中的乘运算,以第二数值参与第一FMA指令中的加运算,并删除所述临时指令;其中,第一数值为第一常量与第三常量的乘积,第二数值为第二常量与第三常量的乘积。
7.根据权利要求5所述的GPU编译器优化方法,其特征在于,所述对第一窗口中包含有常量参数的指令进行优化包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一ADD指令时,则执行以下过程:
若在所述第一ADD指令中,所述临时变量与第三常量一同参与加运算,则将所述第一ADD指令变更为第一FMA指令,所述第一FMA指令使用所述临时指令中的第一常量与第一变量一同参与乘运算,使用第一数值参与加运算,删除所述临时指令;其中,所述第一数值为第二常量与第三常量的和;
若在所述第一ADD指令中,所述临时变量与第一变量一同参与加运算,则将所述第一ADD指令变更为第二FMA指令,所述第二FMA指令使用第二数值和所述临时指令中的第一变量一同参与乘运算,使用所述临时指令中的第二变量参与加运算,删除所述临时指令;其中,所述第二数值为所述第一常量加1所得的值。
8.根据权利要求5所述的GPU编译器优化方法,其特征在于,所述对第一窗口中包含有常量参数的指令进行优化包括:
若第一窗口中的临时指令为FMA指令,所述FMA指令中存在第一常量与第一变量一同参与乘运算,且存在第二常量参与加运算,且在所述临时指令后,存在一条使用临时变量参与加运算的第一FMA指令时,
若在所述第一FMA指令中,第三常量与临时变量一同参与乘运算,第四常量参与加运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和所述第一变量,将所述第一FMA指令中的加参数替换为第二数值,删除所述临时指令;其中,所述第一数值为第一常量与第三常量的乘积,所述第二数值为第二常量与第三常量的乘积再加上第四常量所得的总和;
若在所述临时指令后,存在一条使用临时变量参与乘运算的第二FMA指令时,且在所述第二FMA指令中,第三常量与第一变量一同参与乘运算,临时变量参与加运算,则将所述第二FMA指令中的第二常量替换为第三数值,将所述第二FMA指令中的加参数替换为第二常量,删除所述临时指令;其中,所述第三数值为第一常量与第二常量的和。
9.根据权利要求5所述的GPU编译器优化方法,其特征在于,所述对第一窗口中包含有常量参数的指令进行优化包括:
若在第一窗口的第一FMA指令中,使用临时变量和第一常量参与乘运算,使用第二常量参与加运算,且所述临时变量所对应的临时命令为MUL命令或ADD命令时,
若所述临时命令为MUL命令,且在所述临时命令中,使用第三常量和第一变量参与乘运算,则将所述第一FMA指令中的两个乘参数分别替换为第一数值和第一变量,删除所述临时指令;其中,所述第一数值为第三常量与第一常量的乘积;
若所述临时命令为ADD命令,且在所述临时命令中,使用第三常量和第一变量参与加运算,则将所述第一FMA指令中的临时变量替换为第一变量,并将所述第一FMA指令中的第二常量替换为第二数值,删除所述临时指令;其中,所述第二数值为第一常量与第三常量的乘积再加上第二常量的总和。
10.根据权利要求5所述的GPU编译器优化方法,其特征在于,所述方法还包括:
在执行FMA指令模板匹配优化之前,检查基本块中的指令是否包含除法操作,如果是,则将第二个操作数变成其倒数,将除法变成乘法操作,再和已定义的乘加指令模板进行匹配;
扩展上述指令模板,将指令模板中的加号相应的替换为减号,增加模板数量,扩大模板匹配和优化的范围;
执行模板匹配优化之后,对于不支持FMA指令的CPU、DSP和ASIC处理器后端,将优化后的FMA指令转换成一条乘法指令和一条加法指令。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211563572.1A CN115964048A (zh) | 2022-12-07 | 2022-12-07 | 一种gpu编译器优化方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211563572.1A CN115964048A (zh) | 2022-12-07 | 2022-12-07 | 一种gpu编译器优化方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115964048A true CN115964048A (zh) | 2023-04-14 |
Family
ID=87357914
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202211563572.1A Pending CN115964048A (zh) | 2022-12-07 | 2022-12-07 | 一种gpu编译器优化方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115964048A (zh) |
-
2022
- 2022-12-07 CN CN202211563572.1A patent/CN115964048A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US6286135B1 (en) | Cost-sensitive SSA-based strength reduction algorithm for a machine with predication support and segmented addresses | |
US20060098019A1 (en) | Automated construction of shader programs | |
Mitchell et al. | Uniform boilerplate and list processing | |
Brady et al. | Scrapping your inefficient engine: using partial evaluation to improve domain-specific language implementation | |
Farmer et al. | The HERMIT in the stream: fusing stream fusion's concatMap | |
KR20080096306A (ko) | 규칙에 기반하여 스케일링 쉬프트의 최적의 위치를 찾는컴파일 방법 및 시스템 | |
Stucki et al. | Multi-stage programming with generative and analytical macros | |
Bahmann et al. | Perfect reconstructability of control flow from demand dependence graphs | |
CN115964048A (zh) | 一种gpu编译器优化方法 | |
Rendl | Effective compilation of constraint models | |
US20060059476A1 (en) | Apparatus and method for linear dead store elimination | |
US7574703B2 (en) | Method and apparatus for reducing instruction dependencies in extended SSA form instructions | |
Saraiva et al. | Data structure free compilation | |
Yang et al. | VizGen: accelerating visual computing prototypes in dynamic languages | |
Goubault | Generalized boxings, congruences and partial inlining | |
Webb et al. | Verifying term graph optimizations using Isabelle/HOL | |
Racordon | From ASTs to Machine Code with LLVM | |
Anlauff et al. | Enhanced control flow graphs in Montages | |
Stucki et al. | Proof of Multi-Stage Programming with Generative and Analytical Macros | |
Sheard et al. | Search-based binding time analysis using type-directed pruning | |
Cunha et al. | Algebraic specialization of generic functions for recursive types | |
Kats et al. | Interactive disambiguation of meta programs with concrete object syntax | |
US20240135210A1 (en) | Replacing lambda expressions in a rete network with corresponding code classes | |
Macedo et al. | Efficient Embedding of Strategic Attribute Grammars via Memoization | |
Hupel | Certifying Dictionary Construction in Isabelle/HOL |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |