具有精确相关的样本驱动的简档引导优化的制作方法

文档序号:17850544发布日期:2019-06-11 22:09阅读:206来源:国知局

本实施例涉及用于编译软件程序以供在计算系统上执行的技术,并且更具体地涉及基于用于在简档引导优化中使用的采样指令来创建简档数据的方法、设备和系统。



技术实现要素:

提供本“发明内容”是为了以简化的形式介绍一些概念,这些概念将在下面的“具体实施方式”中被进一步描述。本“发明内容”不旨在标识所要求保护的主题的关键特征或必要特征,也不旨在用于限制所要求保护的主题的范围。

编译器优化被用于生成高效运行并且高效利用资源的可执行代码。这些优化受益于程序将如何使用生产输入而执行的知识。简档引导的优化获取从程序的样本运行生成的信息或简档数据,以在执行更适合目标环境的优化中引导编译器。该简档数据可以包括对与基本块相关联的指令被执行的次数的计数。以这种方式,与不频繁地执行的区域相比,编译器能够更积极地优化程序的更频繁地执行的区域。

为了将计数与源代码相关联,相关数据被生成,其将从样本运行采样的处理器指令映射到与对应于该处理器指令的源代码相关联的基本块。相关数据包括程序的每个函数的控制流表示,其标识该函数的基本块。每个基本块包含一系列相对虚拟地址,这些相对虚拟地址对应于与源代码控制流程中的基本块相关联的指令。然后,来自样本运行的块计数被用于更新对应基本块的块计数。然后,具有块计数的相关数据被视为样本简档数据,该样本简档数据然后被用于得出边缘计数,这些边缘计数被用于确定要对程序的某些部分执行的优化和优化的程度。

用户可以可视化样本简档数据,编辑源代码,运行附加的样本运行以获取更多的块计数,并且以任何顺序迭代地重新编译程序,以便针对预期用途获取期望的优化级别。

通过对以下详细描述的阅读和对相关附图的回顾,这些和其他特征和优点将变得明显。应当理解,前面的一般性描述和以下的详细描述都只是说明性的,而不是对所要求保护的各方面的限制。

附图说明

图1示出了用于利用样本驱动的简档引导优化来优化软件程序的示例性系统。

图2是示出用于执行编译以生成相关数据的示例性方法的流程图。

图3是示出用于将目标文件链接成镜像文件并且利用相对虚拟地址来更新相关数据的示例性方法的流程图。

图4是示出用于生成具有块和边缘计数的样本简档数据的示例性方法的框图。

图5是示出用于利用spd文件优化程序的示例性方法的框图。

图6a-6d示出了针对示例性程序生成样本简档数据的示例。

图7是示出第一示例性计算或操作环境的框图。

图8是示出第二示例性计算或操作环境的框图。

具体实施方式

概述

编译器通常执行代码优化以便生成更快执行并且高效地使用存储器的代码。这些代码优化可以包括内联、代码提升、死存储消除、消除公共子表达式、循环展开、代码移动、归纳变量消除、强度降低等。传统的编译器基于静态源代码文件执行这些代码优化,而不知道将在运行时使用的、无法从静态源代码文件获取的输入。

简档引导优化(pgo)是一种使用从程序的样本运行生成的信息来在执行优化中引导编译器以更好地适合预期的目标环境的技术。在样本运行期间收集的信息被称为简档数据。样本运行可以基于具有实字(realword)输入的测试场景。利用基于真实世界输入的简档数据,编译器能够被引导以决定哪些优化最适合目标环境以及如何执行优化。例如,对程序的哪些部分被更繁重地执行的知识允许编译器优化与较不频繁使用的程序的那些区域相比被更繁重地执行的部分。

插桩(instrumentation)pgo是一种类型的pgo技术。在该技术中,探针或特殊指令被插入到程序的二进制表示中。探针用于在程序的执行期间收集信息。然后编译经插桩的二进制文件以形成使用测试输入运行的经插桩的可执行文件。然后,在没有经插桩的代码的情况下,在程序的后续编译中使用由这些样本运行产生的简档数据以优化程序。然而,基于插桩的pgo要求对程序进行修改以便对程序进行插桩以收集简档数据。经插桩的程序中的附加代码增加了程序的执行时间并且改变了简档数据的质量。

硬件事件采样是另一种pgo技术,其具有不需要对程序进行任何修改的优点。某些处理器具有硬件性能计数器,其用于对在处理器的操作期间发生的事件或操作进行计数。例如,一些处理器包括用于对存储器访问、高速缓存未命中、被执行的指令、未被执行的指令、分支误预测、时钟周期等进行计数的计数器。性能监测单元(pmu)通常耦合到处理器,并且用于在计数器溢出时读取计数器。pmu在计数器溢出时向程序生成中断,并且记录当前被执行的指令的地址和一个或多个计数器的值。然而,需要有一种方式将采样指令的地址映射到其对应的源位置,以便来自计数器的信息可用于编译器的优化。

本文中公开的主题通过生成将采样指令的地址映射到程序的基本块的相关数据来克服该限制。该映射利用与每个基本块和采样指令相关联的相对虚拟地址(rva)范围。以这种方式,可以将与采样指令相关联的计数添加到其对应的基本块的块计数中。然后,块计数被用来得出边缘计数,并且标识程序中的哪些区域比其他较不频繁使用的区域被更繁重地经过。该信息对于在针对具有高效存储器使用的更快执行而优化程序中的编译器而言至关重要。

相关数据包括程序的每个函数的控制流表示连同块到rva的映射。块到rva的映射标识与特定基本块相关联的rva的范围。程序中基本块的标识是未知的,直到编译器执行控制流分析。由编译器使用的中间代码表示(ir)语句不与地址相关联。在代码链接之前,编译器为每个ir语句生成相对于函数中的位置的偏移。该偏移是与基本块相关联的偏移的范围的一部分。在链接时,函数的起始rva是已知的,因此链接器将利用基于其相关联的函数的起始rva的相对虚拟地址来替换偏移。

本技术具有相对于现有解决方案的若干益处。相关数据更精确,因为相关数据是在编译器生成的代码上利用从编译器生成的代码到源代码控制流表示中的基本块的直接映射而被生成,而不是依赖于源代码行号信息。

由于存在通过rva从硬件指令到块的直接映射,因此相关数据更高效。这比可以利用调试信息来映射到一行源代码的其他技术更高效,因为它是不依赖于诸如调试信息等中间引用的直接映射。

另外,映射到基本块产生更准确的块计数,因为多个基本块可以与一行源代码相关联。编译器优化更改代码,使得指令被分散开来并且可能属于不同的不相交的rva范围。这可归因于诸如控制流优化和代码复制的将指令移动到程序中的多个区域的优化,或者在源代码中的宏扩展的情况下。映射到源代码行号无法区分利用特定源代码语句的多个块。

另外,映射(例如,spd文件)允许编译器存储关于应当如何在相关数据的控制流表示中调节原始采样计数的提示。提示可以基于优化如何转换程序并且稍后可以被用于更准确地从计数中恢复来自采样的任何不一致。

具有精确相关的样本驱动的简档引导优化

现在将注意力转向图1,其示出了被配置用于样本驱动的简档引导优化的示例性系统和过程100。图1示出了系统的示例性配置,该系统生成相关数据102,收集样本以生成样本简档数据104,并且利用样本简档数据来编译程序106。最初,从程序的初始编译(编程器110)生成相关数据122。当程序的每个源代码文件108被编译时,生成对应的目标文件112,目标文件112包括目标代码116和相关数据118。相关数据118包括源代码108的每个函数的控制流表示连通控制流中每个基本块的块到偏移映射。然后链接目标代码文件112(链接器114)并且生成相应的镜像文件120或可执行文件。链接器114利用与每个基本块相关联的、基于其相关联的函数的起始rva的相对虚拟地址(即,虚拟地址)来更新相关数据122。

接下来,在一个或多个样本运行124期间使用来自每个样本运行124的各种输入和输出硬件指令轨迹来执行镜像文件120。来自多个样本运行124的硬件指令轨迹或样本数据126通过收集器128被收集和格式化成样本简档跟踪(“spt”)数据130。spt数据130包含与采样指令相关联的一系列操作码、rva和计数三元组。然后,将spt数据130与相关数据122相关联以生成样本程序数据(“spd”)文件134。

spd文件134包括具有块计数的相关数据。块计数表示基本块的硬件指令被执行的次数。块计数基于来自指令跟踪的计数。然后,在源代码文件108、140的后续简档优化编译(编译器136)中使用spd文件134。该编译还更新spd文件134中的数据,以生成经更新的spd144。经更新的spd144包含反映当前源代码的相关数据,并且还包含从尚未被编辑的函数的输入spd带来的计数。链接器138从该编译接收目标代码文件142和经更新的spd文件144,并且形成适合于执行的镜像文件148(框152)。

尽管图1描绘了特定配置中的系统和过程,但是应当注意,开发者能够以任何预期的方式改变图1所示的步骤。例如,开发者可以利用使用不同输入的附加样本运行来更新spd文件(框154)。在一个方面,spd文件可以是滚动简档,其中计数在附加样本数据被生成时随时间到期。例如,可以按日期对块计数进行加权,并且可以在更新的样本数据被生成时使较旧的计数淘汰。备选地,可以丢弃现有的块计数并且将其替换为来自新的样本数据的计数。可以丢弃早于预定阈值的块计数,并且将其替换为来自新的样本数据的计数。可以基于样本数据被获取的时间将权重与样本数据相关联,并且块计数可以基于计数的加权平均值。

另外,开发者可以编辑源代码(框156),源代码可以使用具有附加输入的spd文件134而被重新优化。另外,开发者可以可视化spd文件146(框150)以用于进一步分析,并且然后利用附加样本运行来更新spd文件(框154)。系统不受任何特定动作序列的约束,并且被配置为使得开发者可以重复生成spd文件,使用特定版本的spd优化程序,执行程序,可视化spd文件,编辑源代码,以及以任何预期的方式重新优化程序。

现在注意力转向对图1所示的用于生成相关数据和目标文件的编译(编译器110)的进一步讨论。转到图2,示出了用于编译程序的每个源代码文件202的示例性方法200。应当注意,方法200可以表示由本文中描述的一个或多个方面执行的一些或全部操作,并且该方法可以包括比图2中描述的操作更多或更少的操作。

编译是将源代码转换为可执行代码的过程。在一个方面,编译由前端编译器220和后端编译器224在两个阶段中执行。前端编译器220将源代码文件202变换为中间代码表示210,并且后端编译器224将中间代码表示210变换为可执行文件,诸如对象文件218。

如图2所示,前端编译器220可以在包括词法分析(框204)、语义和句法分析(框206)和中间代码生成(框208)在内的阶段中操作。词法分析(框204)将字符流分析为标记。句法分析(框206)或解析获取标记并且检查标记的布置是否遵循底层编程语言的语法。句法分析(框206)输出解析树或语法树。语义分析(框206)检查解析树的语义正确性,诸如执行类型检查并且检查函数调用中的参数的数目是否正确等等。中间代码生成(框208)生成中间代码表示,中间代码表示是源代码的机器和语言无关的版本。中间代码表示可以用字节码、公共中间语言(“cil”)、gnu寄存器传送语言(“gnurtl”)、解析树、树表示或由编译器或语言虚拟机使用的任何其他类型的数据结构或格式来表示。

后端编译器224接收中间代码表示210并且扫描该代码以为程序中的每个函数生成控制流表示。控制流表示是抽象函数的控制流行为的数据结构。函数是执行特定任务的一组源代码语句。函数可以来自内置的函数库,也可以是在自源代码中由用户定义的。控制流表示是如下数据结构,其通过将ir语句分组为基本块来表示通过程序的流,其中每个基本块包含具有仅一个入口点和仅一个出口点的顺序排序的ir语句。控制流表示中的基本块表示具有单个入口和单个出口点的指令序列,并且连接基本块的边缘表示从一个基本块到另一基本块的函数内的控制流。

后端编译器224还生成包括函数的控制流表示和块到偏移映射的相关数据。块到偏移映射将函数的每个基本块与一系列偏移相关联。每个偏移与作为基本块一部分的指令相关联,并且是相对于函数的开始的。

然后,后端编译器224对中间代码表示210执行各种优化,其可以包括但不限于以下中的一项或多项:内联;代码提升;死代码消除;消除公共子表达式;循环展开;归纳变量消除;强度降低等等。内联使用函数的源代码来扩展函数体,以消除与调用函数和从函数返回相关联的开销。代码提升将循环不变的源代码语句移出循环,使得语句只被执行一次而不是在每次循环迭代处都被执行。死代码消除是指消除无法访问或未被执行的代码。公共子表达式消除是指消除先前计算的并且其中自先前计算以来表达式的值未发生变化的表达式。循环展开通过复制循环体的源代码来减少循环中的迭代次数。归纳变量消除将多个归纳变量组合成单个归纳变量。强度降低将计算密集型操作替换为计算密集度较低的操作。应当注意,本文中描述的本发明的各方面不限于前述编译器优化。其他编译器优化也可以被利用,并且本文中描述的优化不旨在暗示对这些方面的功能的任何限制。

编译的最后阶段是代码生成阶段(框216)。后端编译器224向寄存器指派变量(即,寄存器分配)并且为目标处理单元生成机器指令,该机器指令被输出到目标代码文件218。在一个方面,目标代码文件218包括目标代码和相关数据。该组合的目标代码文件和相关数据218被发送到链接器用于进一步处理。

转到图3,进一步详细地示出了图1的链接器114的动作。链接器308接收目标代码文件302中的每一个并且将它们链接成单个可执行文件或镜像文件310中(框304)。链接器308将目标文件中的每一个中的相关数据组装成单个相关数据文件312(框306)。链接器308将每个函数的基本块中的偏移范围替换为rva范围(框306)。备选地,每个函数的起始rva可以被存储在spd中。rva范围是相对于对应函数的起始rva的。

现在注意力回到图1,以更详细地描述生成样本简档数据的方式。在各种样本运行124中利用表示不同场景的真实世界输入来执行镜像文件120以生成样本数据126。在每个样本运行124的执行期间,生成硬件指令的样本(即,样本数据126)。存在可以用于生成样本数据126的各种性能监测工具,诸如但不限于microsoft的xperf、intel的vtune、oracle的硬件活动报告器(har)、windows的事件跟踪(etw)等。从这些不同的性能监测工具输出的数据格式不同。收集器128接收不同格式的样本数据126,并且将它们转换成统一格式:样本数据跟踪(“spt”)格式。spt格式至少包括操作码、rva和计数。spt数据130然后由spd转换器132使用以生成spd134连同相关数据122。

现在注意力转到图4,其示出了spd转换器132的示例性方法400。spd转换器132接收spt数据130和相关数据122。相关数据122是没有块计数的spd文件。spd转换器132读取每个spt记录(框402)并且在相关数据122中搜索与spt记录相匹配的控制流表示(框404)。这是通过将spt记录中的rva与具有包括spt记录中的rva的rva范围的控制流表示相匹配来完成的(框404)。基于spt记录中的rva在匹配块的rva范围内来寻找对应的块标识符(框406)。

然后,spd转换器132确定样本的rva范围是否包括内联。相关数据包括每个内联函数的块到rva映射,每个内联实例一个映射。如果是(框408-是),则在相关数据中寻找内联的控制流表示(框410),并且该过程继续(框406)以搜索内联的控制流表示,直到其到达不具有内联的块(框408-否)。一旦找到(框408-否),则利用来自spt记录的计数来更新该块的块计数(框412)。如果样本不属于内联范围(框408-否),则利用来自spt记录的计数来更新该块的块计数(框412)。重复该过程,直到所有spt记录被处理(框402)。

一旦所有spt记录被处理,则每个块的块计数被后处理并且然后被用于估计边缘计数(框414)。边缘计数是控制流表示的基本块的边缘进入(即,传入边缘)或输出(即,传出边缘)被经过或执行的次数。块的传入边缘计数是从边缘的源块(即,前导块)传送到基本块的执行次数,而基本块的传出边缘计数是从基本块传送到边缘的接收块(即,后继块)的执行次数。在理想情况下,基本块的所有传入边缘的计数应当等于该块的所有传出边缘的计数。后处理启发式地调节块计数和边缘计数,使得块计数和边缘计数满足流守恒规则,即,对于每个基本块,传入边缘的计数总和等于传出边缘计数的总和。例如,该后处理可以将边缘计数改变为传入边缘计数和传出边缘计数的平均值。然而,应当注意,本文中描述的技术不限于这种特定的启发法,并且可以采用其他启发法。

返回图1,一旦spd文件134被生成,则使用spd文件编译程序的每个源代码文件以优化程序。这在图5中更详细地描述。编译500可以由单个编译器或使用前端和后端编译器执行,并且被认为是简档优化编译器136,因为它利用spd文件134。如前所述,编译可以在包括词法分析阶段(框504)、语义和句法分析阶段(框506)、中间代码生成阶段(框508)在内的多个阶段中被执行。中间代码生成阶段(框508)生成源代码的中间代码表示。优化阶段(框514)执行代码优化,并且代码生成阶段(框516)生成目标代码文件518。

在优化阶段之前,编译器分析spd文件134以确定哪些代码优化将在程序的哪些区域上执行(框512)。例如,编译器可以确定程序的哪些函数以及函数的哪些块被更频繁地执行,它们需要更多优化。块计数可以被用于确定应当内联程序的哪些函数。可以通过将更频繁地执行的代码放在一起并且将较不频繁的代码放在一起来优化代码布局。

回到图1,现在注意力转向更新spd(框154)。用户可以在任何时间想要创建具有不同样本数据的新spd文件,或者将附加样本数据添加到现有spd文件。在任何一种情况下,spd文件都可以相应地更新。附加的样本运行可以被执行(框124),其生成新的样本数据126,收集器128将新的样本数据126格式化为spt数据130。spd生成器132可以将新的spt数据与相关数据合并以创建新的spd文件,或者将新的spd数据与现有spd文件合并。另外,用户可以在任何时间编辑程序的源代码(框156),并且重新编译程序以进一步优化程序(框136)。

现在注意力转向图6a-6d,其示出了示例性程序的spd文件的创建。转到图6a,示出了在初始编译和链接之前具有函数foo()的示例性源代码列表602的示例性系统和过程600。示出了函数foo()的控制流表示604的图示。控制流表示604包括标记为b1-b5的5个基本块。基本块b1表示代码语句intfoo(intx)或函数prolog,基本块b2表示代码语句if(x&1),基本块b3表示代码语句bar(x);bar(x+1);基本块b4表示代码语句baz(x);baz(x-1);并且基本块b5表示代码语句return3。

函数foo()的相关数据606被示出为包括用于每个基本块608、610、612、614、616的单独条目的表。每个条目包括用于函数foo()中的每个基本块的唯一块标识符、块计数、一个或多个rva范围(其中每个rva范围包括起始偏移和长度)、表示跟随的基本块的后继字段、以及表示该函数是否具有内联代码的内联字段。如图6a所示,相关数据606不具有块计数(即,块计数=0)或内联代码(内联=y)。

图6b示出了包括函数main()的第二示例性源代码程序620,该函数main()内联图6a所示的函数foo()。对应的控制流表示622包括标记为b1-b4的4个基本块。基本块b1表示代码语句main(),基本块b2表示具有内联的函数foo()的控制流表示的代码语句iffoo(x),基本块b3表示代码语句printf("non-zero"),并且基本块b4表示代码语句return0。

图6c示出了图6b所示的第二示例性源代码程序620main()的相关数据630。函数main()的相关数据630被示出为包括main()636、638、642、644中的每个基本块b1-b4的单独条目的表。main()的基本块b2的相关数据630包括foo()的相关数据606。main()的b2的内联字段指示b2具有内联函数(即,内联=y)并且包括foo()640的相关数据。应当注意,相关数据是其中基本块包括所有内联函数的相关数据的分层表。例如,如果foo()要包括baz()的内联代码,则baz()的相关数据将是foo()的相关表的一部分。

图6c还示出了spt数据632。spd转换器132获取spt数据632并且将spt数据632中的计数与相关数据630中的对应基本块的块计数合并。如上所述,与spt数据记录相对应的基本块具有与spt数据记录中的rva相匹配的一系列rva。相关数据630中的块计数为零。然而,在spt数据632被合并到相关数据630中之后,块计数出现在相关数据中,由此生成spd文件634。spd文件634包括相关数据630和来自spt数据632的块计数。

转到图6d,示出了没有边缘计数的spd文件634和具有边缘计数的对应spd文件646。当spd转换器132执行后处理时,spd转换器132为每个控制流表示的每个基本块中的每个边缘添加边缘计数。如spd文件646中所示,存在foo()的内联实例的控制流表示的边缘计数648和main()的控制流表示的边缘计数650。foo()的内联实例的边缘计数648包括边缘b1->b2的边缘计数55、边缘b2->b3的边缘计数15、边缘b2->b4的边缘计数40、边缘b3->b5的边缘计数为15和边缘b4->b5的边缘计数40。main()的边缘计数650包括边缘b1->b2的边缘计数55、边缘b2->b3的边缘计数45、边缘b2->b4的边缘计数10和边缘b3->b4的边缘计数45。

以上述方式生成spd文件具有若干优点。采样指令不会追溯到特定的源代码行号或调试行号,而是追溯到与其中间代码表示相关联的基本块。以这种方式,块计数考虑被内联并且由于优化而已经重新定位到程序的不同块的指令,由此产生更准确的块计数。从硬件指令到基本块的映射是仅利用rva的直接映射。此外,由于块计数是程序的控制流表示的一部分,因此编译器的优化器更容易访问它们,因为优化器利用控制流图来执行大多数优化。

根据本文中描述的主题的各方面,一种计算机系统可以包括一个或多个处理器、连接到一个或多个处理器的存储器、一个或多个编译器、链接器和spd转换器。一个或多个编译器包括一个或多个模块,该一个或多个模块在被加载到存储器中时引起一个或多个处理器编译和优化源代码文件,并且生成相关数据。相关数据包括源代码的控制流表示形式的控制流图和块到偏移映射。控制流表示包括多个基本块。链接器包括一个或多个模块,该一个或多个模块在被加载到存储器中时引起一个或多个处理器将程序的优化目标文件链接成镜像文件,并且将块到偏移映射中的偏移替换为对应的相对虚拟地址(rva)。rva是从镜像文件中的基本块相关联的函数的起始地址起的相对地址。spd转换器包括一个或多个模块,该一个或多个模块在被加载到存储器中时引起一个或多个处理器从样本运行中获取样本数据,该样本数据被转换为spt格式并且被用于为存储在spd文件中的函数的每个基本块生成块和边缘计数。可以进行附加的样本运行,并且可以将来自那些样本运行的样本数据合并到spd文件中的块和边缘计数中。如果旧的块计数比门限更旧则可以使其到期,或者将其替换为新的计数。可以基于样本数据被获取的时间将权重与样本数据相关联,并且可以使用计数的加权平均值。一个或多个编译器中的至少一个编译器是利用样本简档数据的块和/或边缘计数来优化程序的简档优化编译器。

一种使用诸如上述系统等系统的方法可以包括各种操作,诸如从程序的执行中获取样本数据,该样本数据包括硬件指令的相对虚拟地址和对该硬件指令已经被执行的次数的计数。硬件指令的相对虚拟地址与程序的源代码控制流表示的对应基本块相匹配。与匹配的基本块相关联的块计数被更新以包括计数和块计数,并且其相关联的边缘计数在程序的优化中被使用。在程序的编译期间生成相关数据,以将硬件指令的相对虚拟地址映射到其相关联的基本块。相关数据还包括程序的控制流表示和块到偏移映射,控制流表示包括基本块。基于程序的链接镜像将块到偏移映射转换为块到rva映射。来自样本运行的样本数据被获取并且被转换为包含rva和与硬件指令关联的计数的格式。与基本块相关联的块计数考虑被包括在基本块中的每个内联函数。可以利用来自附加样本运行的样本数据来更新块计数。这些块计数可以合并到现有块计数中,并且合并的块计数可以被用于重新优化程序。可以使用退出块计数或合并的块计数来编辑和重新优化程序。

一种设备可以包括一个或多个处理器、连接到至少一个处理器的存储器、以及至少一个模块,该至少一个模块被加载到存储器中以引起至少一个处理器为程序的至少一个函数生成包括至少一个基本块的控制流表示,该至少一个基本块具有与作为基本块的一部分的指令相关联的一系列虚拟地址和块计数。至少一个模块获取包括虚拟地址和计数的硬件指令。指令样本的虚拟地址被用于寻找与指令样本相关联的控制流表示的基本块。更新与匹配的基本块相关联的块计数。使用来自包括块计数的控制流表示的数据来优化程序。

合适的计算环境的示例

现在注意力转向对示例性操作环境的讨论。图7描绘了包括集成开发环境(“ide”)702和公共语言运行时(“clr”)704的第一示例性操作环境700。ide702(例如,visualstudio、netbeans、eclipse、jetbrains、netcode等)可以允许用户(例如,开发者、程序员、设计者、编码者等)在计算设备中设计、编码、编译、测试、运行、编辑、调试或构建程序、程序集、网站、web应用、分组、以及web服务。软件程序包括以一种或多种源代码语言(例如,visualbasic、visualj#、c++、c#、j#、javascript、apl、cobol、pascal、eiffel、haskell、ml、oberon、perl、python、scheme、smalltalk等)创建的源代码710。

ide702可以提供原生代码开发环境,或者可以提供在语言虚拟机上运行的托管代码开发,或者可以提供其组合。ide702可以使用.net框架提供托管代码开发环境,该.net框架可以包括用户界面706、源代码编辑器708、前端编译器712、收集器716、spd转换器720和可视化器722。用户可以经由ide702中的用户界面706和源代码编辑器708根据已知的软件编程技术以及与特定源语言相关联的特定逻辑和语法规则来创建和/或编辑源代码。此后,可以经由前端编译器712编译源代码710,由此创建程序的中间代码表示726和相关数据714。

另外,ide702可以使用收集器716和spd转换器720来生成spd文件724,收集器716从程序的各种样本运行中收集和聚集样本数据718,spd转换器720从样本数据生成块计数到spd文件724中,spd文件724可以由通过可视化器722的使用来被查看。对象代码或原生代码730a-730n是在程序被执行时使用语言特定的编译器或后端编译器728从中间代码表示726和spd文件724创建的。也就是说,当中间代码表示726被执行时,其被编译并被链接(链接器732),同时被执行为针对其正在其上被执行的平台的适当的机器语言,由此使得镜像文件734跨若干平台可移植。备选地,在其他实施例中,可以将程序编译为适合于其预期平台的原生代码机器语言(未示出)。

在本发明的一个方面,ide702可以在第一计算设备740上操作,并且clr704可以在与第一计算设备740不同的第二计算设备736上操作。在本发明的另一方面,ide702和clr704可以在同一计算设备上操作。计算设备736、740可以是任何类型的电子设备,诸如但不限于移动设备、个人数字助理、移动计算设备、智能电话、蜂窝电话、手持式计算机、服务器、服务器阵列或服务器群、web服务器、网络服务器、刀片服务器、因特网服务器、工作站、小型计算机、大型计算机、超级计算机、网络设备、web设备、分布式计算系统、多处理器系统或其组合。

第一计算设备736和第二计算设备740可以通过通信框架738通信地耦合。通信框架738促进计算设备之间的通信。通信框架738可以实施任何公知的通信技术,诸如适用于分组交换网络的技术(例如,诸如因特网的公共网络、诸如企业内联网的专用网络等)、电路交换网络(例如,公共交换电话网络)、或分组交换网络和电路交换网络的组合(具有合适的网关和转换器)。

尽管已经关于.net框架描述了前述操作环境,但是本文中描述的技术不限于任何特定的软件框架、编程语言、编译器集合、操作系统、操作系统平台、编译器基础设施项目等。本文中描述的技术可以被实施在gnu编译器集合(gcc)和低级虚拟机(llvm)编译器基础设施以及其他编译器和操作系统中。

现在注意力转向图8和第二示例性操作环境的讨论。应当注意,操作环境800是示例性的,并且不旨在暗示对实施例的功能的任何限制。实施例可以被应用于利用至少一个计算设备802的操作环境800。计算设备802可以是任何类型的电子设备,诸如但不限于移动设备、个人数字助理、移动计算设备、智能电话、蜂窝电话、手持式计算机、服务器、服务器阵列或服务器群、web服务器、网络服务器、刀片服务器、因特网服务器、工作站、小型计算机、大型计算机、超级计算机、网络设备、web设备、分布式计算系统、多处理器系统或其组合。操作环境800可以被配置在网络环境、分布式环境、多处理器环境或者可以访问远程或本地存储设备的独立计算设备中。

计算设备802可以包括一个或多个处理器804、通信接口806、存储设备808、一个或多个输入设备810、一个或多个性能监测单元(pmu)812、输出设备816和存储器814。处理器804可以是任何商业上可获得的处理器,并且可以包括双微处理器和多处理器架构。通信接口806促进计算设备802与其他设备之间的有线或无线通信。存储设备808可以是不包含传播信号在内的计算机可读介质,传播信号诸如通过载波传输的调制数据信号。存储设备808的示例包括但不限于ram、rom、eeprom、闪存或其他存储器技术、cd-rom、数字通用盘(dvd)或其他光学存储设备、磁带盒、磁带、磁盘存储设备,所有这些都不包含传播信号,诸如通过载波传输的调制数据信号。输入设备810可以包括键盘、鼠标、笔、语音输入设备、触摸输入设备等,以及它们的任何组合。输出设备816可以包括显示器、扬声器、打印机等,以及它们的任何组合。pmu812包括存储硬件相关活动的计数的一组专用寄存器(例如,硬件计数器),以及读取这些寄存器的相关硬件/软件。

存储器814可以是可以存储可执行过程、应用和数据的任何非暂态计算机可读存储介质。计算机可读存储介质不涉及传播信号,诸如通过载波传输的调制数据信号。它可以是任何类型的非暂态存储器设备(例如,随机存取存储器、只读存储器等)、磁存储设备、易失性存储设备、非易失性存储设备、光存储设备、dvd、cd、软盘驱动器等,其不涉及传播信号,诸如通过载波传输的调制数据信号。存储器814还可以包括一个或多个外部存储设备或远程定位的存储设备,其不涉及传播信号,诸如通过载波传输的调制数据信号。

存储器814可以包含指令、组件和数据。组件是执行特定功能的软件程序,并且另外称为模块、应用等。存储器可以包括操作系统820、前端编译器822、后端编译器824、链接器826、收集器828、spd转换器830、源代码编辑器832、可视化器834、源代码文件836、目标代码文件838、样本数据840、spt数据842、相关数据844、spd文件846、以及各种其他应用、组件和数据848。

尽管用结构特征和/或方法动作特定的语言描述了本主题,但是应当理解,所附权利要求书中限定的主题不必限于上述具体特征或动作。相反,上述具体特征和动作被公开作为实现权利要求的示例形式。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1