优化线程栈存储器的管理的系统、方法和计算机程序产品的制作方法

文档序号:6523329阅读:152来源:国知局
优化线程栈存储器的管理的系统、方法和计算机程序产品的制作方法
【专利摘要】本发明公开了用于优化线程栈存储器分配的系统、方法和计算机程序产品。方法包括以下步骤:接收用于程序的源代码,将源代码转译成中间表示,分析中间表示以标识可使用线程栈存储器中的第一所分配存储器空间的至少两个对象,以及通过以对至少两个对象中的第二对象的引用替换对至少两个对象中的第一对象的引用来修改中间表示。
【专利说明】优化线程栈存储器的管理的系统、方法和计算机程序产品
【技术领域】
[0001]本发明涉及编译器,并且更具体地,涉及存储器分配中的优化。
【背景技术】
[0002]可用于程序的执行的本地存储器是系统架构中的重要资源。该资源的适当管理对于程序的高效执行是至关重要的。理想地,在程序的执行期间,仅分配包括用于当前指令和未来指令的数据的存储器,而包含使用在先前被执行的指令中的数据的任何存储器被解除分配并被返回到自由存储器池。可由程序设计员来管理某一存储器,诸如通过在采用C++所写的程序中使用malloc和free指令以明确地分配和释放存储器块。
[0003]然而,就线程栈存储器(即充当后进先出(LIFO)队列的分配给程序线程的存储器的一部分)而言,程序设计员典型地不管理线程栈存储器。相反,线程栈存储器随程序执行而动态地得以分配。当前编译器通常不解决对于线程栈存储器的高效管理的优化。因此,存在对于解决该问题和/或与现有技术相关联的其他问题的需要。

【发明内容】

[0004]公开了用于优化线程栈存储器分配的系统、方法和计算机程序产品。方法包括以下步骤:接收用于程序的源代码,将源代码转译成中间表示,分析中间表示以标识可使用线程栈存储器中的第一所分配存储器空间的至少两个对象,以及通过以对至少两个对象中的第二对象的引用替换对至少两个对象中的第一对象的引用来修改中间表示。
【专利附图】

【附图说明】
[0005]图1示出根据一个实施例的、用于优化线程栈存储器的分配的方法的流程图;
[0006]图2示出根据一个实施例的、用于优化线程栈存储器的分配的系统;
[0007]图3A示出根据一个实施例的、用于示范性程序的源代码;
[0008]图3B示出根据一个实施例的、与图3A的示范性程序相对应的中间表示;
[0009]图3C示出根据一个实施例的、是图3B的中间表示的经修改版本的中间表示;
[0010]图4示出根据一个实施例的、用于分析中间表示以确定哪些对象可以被分配到线程栈存储器中的相同的存储器空间的方法的流程图;
[0011]图5示出根据一个实施例的并行处理单元;
[0012]图6示出根据一个实施例的、图5的流多处理器;以及
[0013]图7示出在其中可实现各先前实施例的各架构和/或功能性的示例性系统。
【具体实施方式】
[0014]一些常规编译器通过实施数据流分析和将程序指令以使得某些寄存器可以被重新用来在程序执行中的不同时刻存储不同的值的方式进行排序,而在一定程度上优化寄存器的分配。编译器典型地将源代码(例如采用诸如C++的高级语言所写的程序)转译成中间表示(IR),该IR是表示程序的意义(包括执行次序)的数据结构。IR可以是用于抽象机器的中间语言。IR在生成要由处理器执行的机器代码之前使编译器能够实施数据流分析和重新排列程序的次序。
[0015]上文关于寄存器分配所描述的优化不能以相同方式应用到线程栈中的较大存储器结构。在线程栈中所分配的对象的大小可以变化。相反,寄存器具有定义明确的大小,诸如32位。当包括在程序中的指令将值存储在寄存器中时,值必需覆写先前分配到该寄存器的所有数据。线程栈存储器中的对象的表现不同。当值被存储在对象的元素诸如数组的一个条目中时,值覆写先前被存储在该条目中的数据。然而,对象的其它条目可能仍然是有效的并且分配给先前被存储在对象中的数据。尝试跟踪线程栈中的每个条目的数据流分析将变得非常复杂并且本将能够达到的优化可能无效。
[0016]下文所描述的算法实施一个不同类型的数据流分析,其跟踪分配到线程栈存储器的对象(即配栈对象(stack allocated object))在程序的不同部分是否是“活的”。下面的定义贯穿本公开而使用。在本描述的上下文中,如果存储在对象中的数据潜在地由当前指令或未来指令所需要,那么对象在程序中的某个点(即指令)处是活的。对象的def是将数据存储在对象中的指令。对象的def的示例包括存储指令、在指令的左边(LHS)具有指向对象的变量的指令等。指令不需要覆写分配给对象的整个存储器,而仅需要将数据写入对象的一部分中。针对对象的存储器的分配不是对象的def (因为对象中的数据未被初始化)。对象的use是使用具有对配栈对象的访问权的变量的指令。对象的use的示例包括加载指令、涉及指向对象的指针的二进制操作等。
[0017]图1示出根据一个实施例的、用于优化线程栈存储器的分配的方法100的流程图。在步骤102,编译器接收所要编译的程序。程序可以采用高级编程语言来写,所述高级编程语言诸如C++、C# (C sharp)、Java、Cg (用于图形的C)或某一其他高级编程语言。在步骤104,编译器将程序转译成IR。IR可以是中间语言,诸如LLVM (低级虚拟机编译器基础结构)汇编语言、C、三地址码(TAC)或某一其他类型的中间语言。在步骤106,编译器分析IR以标识可使用线程栈存储器中的相同的所分配存储器空间的至少两个对象。一般地,如果对象的寿命不冲突,那么两个对象可以使用相同的所分配存储器空间。换句话说,只要两个对象不被初始化或使用在程序中的相同点处,那么两个对象可以使用相同的所分配存储器空间。
[0018]在步骤108,编译器通过以对至少两个对象中的第二对象的引用替换对至少两个对象中的第一对象的引用来修改IR。在一个实施例中,当两个配栈对象可被分配到相同存储器空间时,编译器将以指向较大对象的新指令来替换指向较小对象的指令(即依据分配给对象的存储器大小)。应注意的是,虽然本文关于优化线程栈存储器的分配而阐述了各可选特征,但是这类特征仅出于示例性目的而阐述并且不应被视为以任何方式加以限制。
[0019]图2示出根据一个实施例的、用于优化线程栈存储器的分配的系统200。如图2所示,系统200包括编译器210、程序201、中间表示(IR)202和经编译的机器代码203。程序201、IR202和机器代码203是存储在计算机系统的存储器中的数据文件。编译器210是存储在存储器中的、可执行的二进制数并配置为由计算机系统的处理器执行。编译器210从存储器读取程序201并且转移程序201中的数据以生成IR202。在一个实施例中,编译器210实现为用于图形处理单元的驱动程序的一部分,并且程序201是由应用所生成并被传送给驱动程序以在图形处理单元上执行的着色器程序。
[0020]在一个实施例中,程序201是文本文件(例如ASCII文本),该文本文件包括多个以人类可读的格式的指令。程序201可以采用诸如C++的高级编程语言来写。IR202包括被抽象成采用中间语言的多个指令的、来自程序201的多个指令的表示。例如,中间语言可以是TAC并且IR202的每个指令表示目标处理器的一个基本操作(例如二进制操作、逻辑操作、加载/存储操作等)。程序201中的指令可能不能在单个时钟周期中执行。例如,如“D=A+B+C”的二进制操作可能不能由处理器在单个时钟周期中执行。因此,采用中间语言,上文所阐述的指令可被分解成采用中间语言的两个指令(例如第一指令“T1=A+B”和第二指令“D=T1+C”)。
[0021]一旦编译器210已生成IR202,编译器就对IR202实施数据流分析。例如,编译器210可以重新排列IR202中的指令的次序。通过改变指令的次序,编译器可能能够以更高效的方式来分配线程栈中的存储器,重新使用相同存储器位置用于程序201中的不同变量。编译器可以分析所重新排列的指令以找到可被指派给相同存储器对象的变量,以及修改IR202中的指令使得程序201中的不同变量可以重新使用线程栈中的相同存储器对象。一旦编译器210已修改IR202并且已对代码做出某些优化,编译器210就编译IR202以生成机器代码203用于由处理器执行。
[0022]图3A示出根据一个实施例的、用于示范性程序201的源代码。如图3A所示,程序201是采用C++写的。程序201将常数N定义为2000并且包括采取三个参数(即整数n、m和k)的函数g的定义。在函数g的每一次调用期间,声明三个整数数组(即变量A、B和C)以及整数值(即变量result)。变量result被初始化为0,而数组A、B和C不立即被初始化。数组A首先被使用在程序201的第11行上,其可以被称为A的def。数组A还被使用在程序201的第14行上,其可以被称为A的use。数组A在程序201的第14行之后不被使用或定义。类似地,数组B首先被使用在程序201的第18行上,数组C首先被使用在程序201的第21行上,并且数组B和C被使用在程序201的第24行上。
[0023]函数g的主体包括If…Else语句。当参数η小于参数m时,If…Else语句的第一块(即程序201的第10-15行)被执行。当参数η大于或等于参数m时,第二块(即程序201的第17-25行)被执行。然后,变量result的值被函数返回。更详细地检查If…Else语句,本领域的技术人员将注意到数组A在第一块中在第一个for循环(即程序201的第10-12行)内被初始化并且然后在第二个for循环(即程序201的第13-15行)内多个A的值被添加到变量result。数组B在第三个for循环(即程序201的第17-19行)中被初始化,数组C在第四个for循环(即程序201的第20-22行)中被初始化,并且然后在第五个for循环(即程序201的第23-25行)内B的每个第k个值乘以C的每个第k个值并被添加到变量result。
[0024]应理解的是,每次函数g被线程调用时,函数将执行If…Else语句的第一块或第二块,而不是第一块和第二块。换句话说,在执行期间,基于条件语句(“n〈m”),或者数组A将被定义并使用在一个或多个指令中,或者数组B和C将被定义并使用在一个或多个指令中。有利地,编译器可以优化用于程序201的IR202使得数组A以及或者数组B或者数组C可被分配给线程栈存储器中的相同对象。相反,因为数组B和数组C可能在程序的相同点处是活的(例如在第五个for循环中来自数组B和数组C这二者的值可以用作相同指令中的操作数),所以数组必须指向线程栈存储器中的不同对象。更一般地,如果两个对象在程序的相同点处不是活的,那么两个对象可被分配到具有至少像两个对象中的较大者的大小那样大的相同存储器空间。换句话说,线程栈存储器的一部分被分配一次并由两个对象来使用。由于标量值典型地由编译器分配给寄存器,所以分配到线程栈存储器的对象典型地是数组或大于单个寄存器的宽度的聚合的值。
[0025]图3B示出根据一个实施例的、与图3A的示范性程序201相对应的IR202。如图3B所示,编译器210已将程序201转译成IR202。在第I到4行,IR202包括用于变量A、B、C和result的分配指令。用于变量A、B和C的对象是2000元素的整数数组,而用于变量result的对象是单个整数。在IR202的第5行中,result的值被初始化为O。IR202的第6行与程序201中的主If…Else语句的条件语句相对应。因此,IR202的第7到23行与程序201中的If…Else语句的第一块相对应,第24到51行与程序201中的If…Else语句的第二块相对应。IR202的第7到14行与程序201中的第一个for循环相对应,第15到23行与程序201中的第二个for循环相对应,第24到31行与程序201中的第三个for循环相对应,第32到39行与程序201中的第四个for循环相对应,以及第40到51行与程序201中的第五个for循环相对应。
[0026]图3C示出根据一个实施例的、是图3B的IR202的经修改版本的IR202-1。如图3C所示,图3B的IR202中的指令中的一些已经被修改以优化线程栈存储器的分配。线程栈存储器的部分被分配给第一数组A、第二数组B以及整数result,所述整数result被初始化为O。不同于IR202,线程栈存储器的部分最初未被分配给第三数组C。IR202-1中的If…Else语句的第一块(即第6到22行)保持与图3B的IR202中的If…Else语句的第一块(即第7到23行)相同。然而,编译器210已修改IR202-1中的If…Else语句的第二块(即第23到50行)以优化线程栈存储器的分配。应理解的是,仅两个数组A和B被分配在IR202-1中。包括引用IR202中的数组B的操作数的指令已被以引用IR202-1中的数组A的操作数所替换。类似地,包括引用IR202中的数组C的操作数的指令已被以引用IR202-1中的数组B的操作数所替换。因此,被分配在IR202-1中的两个数组A和B分别与图3B的IR202的数组B和C相对应。因此,与用于IR202中的三个2000元素的数组的24千字节相t匕,用于IR202-1的所分配线程栈存储器的量是用于IR202-1中的两个2000元素的数组的最大值16千字节(假定变量result被分配给寄存器而不是线程栈存储器)。
[0027]图4示出根据一个实施例的、用于分析IR202以确定哪些对象可被分配到线程栈存储器中的相同存储器空间的方法400的流程图。在步骤402,编译器210标识IR202中的所有配栈对象。编译器210可以逐句通过IR202中的指令的每一个并且确定指令是否使线程栈中的存储器被分配给对象。如果是,那么对象被标识为配栈对象。例如,IR202可以包括分配指令(例如“a=alloc(int,2000) ”),其将线程栈存储器的一部分分配给对象并且将指向对象的指针指派给变量a。
[0028]在步骤404,针对每个配栈对象,编译器210分析IR202以标识具有对配栈对象的访问权的所有变量。换句话说,作为指令的结果,如果在指令的右边(RHS)的一个或多个变量指向对象,那么表示指令的左边(LHS)的变量“指向”对象。例如,如果句柄a被拷贝到b,那么b被认为指向被分配给a的对象并且因此应被跟踪以确定用于a的存储器空间何时正被使用。对其而言结果可指向配栈对象的具体指令是不同的,这取决于由IR202所利用的中间语言。指向配栈对象的指令的类型包括但不限于拷贝指令、二进制操作、转换(例如类型转换)、PHI节点(即用来选择取决于当前块的前驱的值的特殊指令)、存储指令以及函数调用。在一个实施例中,如果变量指向被分配给对象的存储器空间中的任何位置,那么变量被认为指向整个对象(即不仅是对象的特定元素)。表1示出用于标识具有对配栈对象的访问权的所有变量的示范性伪代码:
[0029]表1
[0030]
【权利要求】
1.一种方法,包括: 接收用于程序的源代码; 将所述源代码转译成中间表示(IR); 分析所述IR以标识能使用线程栈存储器中的第一所分配存储器空间的至少两个对象;以及 通过以对所述至少两个对象中的第二对象的引用替换对所述至少两个对象中的第一对象的引用来修改所述IR。
2.根据权利要求1所述的方法,其中所述IR包括LLVM(低级虚拟机编译器基础结构)汇编语目。
3.根据权利要求1所述的方法,其中所述源代码包括由C++、Java、C#以及Cg中的至少一个高级编程语言所指定的多个指令。
4.根据权利要求1所述的方法,其中分析所述IR包括: 标识所述IR中的多个配栈对象; 针对所述多个配栈对象中的每个配栈对象,标识具有对所述配栈对象的访问权的所有变量; 确定哪些配栈对象在所述IR中的相同点处是活的;以及 确定哪些配栈对象能被分`配到所述第一所分配存储器空间。
5.根据权利要求4所述的方法,其中分析所述IR进一步包括生成用于所述多个配栈对象中的每个配栈对象的活性网。
6.根据权利要求5所述的方法,其中所述活性网包括用于所述配栈对象的def和use的合集。
7.根据权利要求1所述的方法,其中将所述源代码转译成所述IR由实现在用于图形处理单元的驱动程序中的编译器实施。
8.根据权利要求7所述的方法,其中所述源代码包括着色器程序。
9.根据权利要求1所述的方法,进一步包括: 分析所述IR以标识能使用所述线程栈存储器中的第二所分配存储器空间的至少两个附加的对象;以及 通过以对所述至少两个附加的对象中的第二对象的引用替换对所述至少两个附加的对象中的第一对象的引用来修改所述IR。
10.根据权利要求9所述的方法,其中分析所述IR以标识至少两个附加的对象包括: 标识与使用所述第一所分配存储器空间的另一个对象冲突的第一附加的对象;以及 标识与使用所述第一所分配存储器空间的另一个对象冲突的至少一个附加的对象。
11.一种存储指令的非易失性计算机可读存储介质,所述指令当由处理器执行时使所述处理器实施步骤,包括: 接收用于程序的源代码; 将所述源代码转译成中间表示(IR); 分析所述IR以标识能使用线程栈存储器中的第一所分配存储器空间的至少两个对象;以及 通过以对所述至少两个对象中的第二对象的引用替换对所述至少两个对象中的第一对象的引用来修改所述IR。
12.根据权利要求11所述的非易失性计算机可读存储介质,其中所述IR包括LLVM(低级虚拟机编译器基础结构)汇编语言。
13.根据权利要求11所述的非易失性计算机可读存储介质,其中分析所述IR包括: 标识所述IR中的多个配栈对象; 针对所述多个配栈对象中的每个配栈对象,标识具有对所述配栈对象的访问权的所有变量; 确定哪些配栈对象在所述IR中的相同点处是活的;以及 确定哪些配栈对象能被分配到所述第一所分配存储器空间。
14.根据权利要求11所述的非易失性计算机可读存储介质,其中分析所述IR进一步包括生成用于所述多个配栈对象中的每个配栈对象的活性网。
15.根据权利要求11所述的非易失性计算机可读存储介质,其中将所述源代码转译成所述IR由实现在用于图形处理单元的驱动程序中的编译器实施。
16.—种系统,包括: 存储器,其配置为存储用于程序的源代码;以及 处理单元,其配置为: 接收所述源代码, 将所述源代码转译成中间 表示(IR), 分析所述IR以标识能使用线程栈存储器中的第一所分配存储器空间的至少两个对象,以及 通过利用以对所述至少两个对象中的第二对象的引用替换对所述至少两个对象中的第一对象的引用来修改所述IR。
17.根据权利要求16所述的系统,其中分析所述IR包括: 标识所述IR中的多个配栈对象; 针对所述多个配栈对象中的每个配栈对象,标识具有对所述配栈对象的访问权的所有变量; 确定哪些配栈对象在所述IR中的相同点处是活的;以及 确定哪些配栈对象能被分配到所述第一所分配存储器空间。
18.根据权利要求16所述的系统,其中所述源代码包括着色器程序。
19.根据权利要求16所述的系统,进一步包括耦连到所述处理单元和所述存储器的图形处理单元。
20.根据权利要求19所述的系统,进一步包括存储在所述存储器中的驱动程序,其中所述驱动程序实现编译器,所述编译器当由所述处理单元执行时将所述处理单元配置为接收所述源代码、将所述源代码转译成所述IR、分析所述IR以及修改所述IR。
【文档编号】G06F9/30GK103870242SQ201310675015
【公开日】2014年6月18日 申请日期:2013年12月11日 优先权日:2012年12月12日
【发明者】阿德里安娜·玛丽亚·苏斯内亚, 维诺德·格罗弗, 肖恩·扬孙·李 申请人:辉达公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1