NI LabVIEW 编译器:深层分析.docx
《NI LabVIEW 编译器:深层分析.docx》由会员分享,可在线阅读,更多相关《NI LabVIEW 编译器:深层分析.docx(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、NI LabVIEW 编译器:深层分析概览即便对无足轻重的编程语言来说,编译器的设计往往也是一个复杂的课题。即使对专业的软件工程师们来说,编译理论也需要考虑专业知识。现代的NI LabVIEW软件是一种多范例语言,包括广泛的多种类型的概念,包括数据流,支持面向对象,以及事件驱动编程。LabVIEW也覆盖了各种平台,服务多种操作系统(Windows, Linux, Mac),多种芯片组(PowerPC, Intel),甚至可以服务于嵌入式设备和现场可编程门阵列(FPGAs),它与传统的PC结构有明显不同。也许您会猜想,LabVIEW编译器是一个精密的系统,远远超出一般书面描述的范围。目录1. 编
2、译与解释2. LabVIEW编译器的历史回顾3. 当今的编译器4. DFIR 与LLVM协同工作本专业论文介绍了LabVIEW编译器,简明地讲解了它从1986年LabVIEW 1.0版本开始的发展变化,并描述了它今天的形式。另外,本文也探究了最近编译器的创新,并突出了这些新特点对LabVIEW的益处以及对您的帮助。编译与解释LabVIEW是一种编译语言,它令人惊奇,因为它在一般的G开发过程没有任何明晰的编译步骤。取而代之的是,您可以对您的VI做出改动并简单地按下运行键来执行它。编译意味着您所写的G代码被转化为本地机器码然后被主机电脑直接执行。这种方法可供选择的另一种途径是解释,程序被另外的软件
3、程序(叫做解释程序)间接地执行,而不是直接由电脑执行。LabVIEW语言并没有要求其本身被编译或者解释;事实上,LabVIEW的第一个版本使用解释程序。在后来的版本,编译器取代了解释程序以提高VI运行时的性能,这是编译器与解释程序相比最常见的区别。解释程序更容易编写,并以较差的运行性能为代价,而编译器执行起来更加复杂但是却能提供更快的执行时间。LabVIEW编译器最主要的好处之一就是编译器对所有VIs的提高显而易见,而不必做出任何改变。实际上,LabVIEW 2010正式版的编译器进行了内部优化以加快VI的执行时间。LabVIEW编译器的历史回顾在急于深入讨论现在编译器内部组成之前,很值得总结
4、一下编译器从20年前最早期版本到现在的发展。这里介绍的一些算法,例如类型传播法,聚丛法,以及内嵌法(inplaceness),在现代的LabVIEW编译器讨论中会更加详细地描述。LabVIEW 1.0版本于1986上市。如前面提到的,LabVIEW在其第一个版本使用了解释程序并且仅为摩托罗拉68000服务。那时的LabVIEW语言非常简单,也减弱了其对编译器的需求(当时是解释程序)。例如,它不存在任何的多态数据类型,唯一的数据类型是扩展精度浮点数据。LabVIEW 1.1版本首次引入了内嵌(inplaceness)算法,或者称之为“内嵌程序”。此算法支持数据分配,因此您可以在执行的时候重新使用
5、数据,避免了不必要的数据副本,相应地,常常能显著地提高执行性能。在LabVIEW 2.0版本,解释程序被当前的编译器所取代。仍然专门为摩托罗拉68000服务,LabVIEW可以生成本地机器码。在2.0版本还增加了类传播算法,可以在不断完善的LabVIEW语言中发挥其它职能,处理语法检查与类型解析。LabVIEW 2.0另外一项重大的创新是聚丛程序的引入。聚丛算法支持LabVIEW图表的并行输入,并将节点归类为“丛”,它可以并行运行。类传播算法,嵌入法(inplaceness)以及聚丛算法直到目前也是现代LabVIEW编译器的重要组成部分,并随时间的推移显现出更多的新增改进。LabVIEW 2.
6、5中新的编译器基本结构增加了对多种后端设备的支持,尤其是英特尔x86与 Sparc。LabVIEW 2.5也引入了连接器,当VIs需要被重新编译的时候,它可以管理VIs路径之间的从属关系。在LabVIEW 3.1,除常数合并外,也增加了两个新的后端,PowerPC 与 HP PA-RISC。LabVIEW 5.0 与6.0 更新了编码生成程序,并增加了GenAPI,一种与多种后端连接的常用接口。GenAPI交叉编译对实时开发来说,是非常重要的。实时开发者一般在主机PC上编写VIs,而将其部署到(将它们编译到)实时对象。另外,一种循环不变代码移出的有限形式也包含在内。最终,LabVIEW多任务执
7、行系统被扩展到支持多线程。LabVIEW 8.0创建的基于5.0版本引入的GenAPI基本结构,新增了寄存器分配算法。在GenAPI引入之前,每个节点的生成码都是由寄存器硬件编码的。不可执行编码的有限形式以及死码删除也被引入。LabVIEW 2009具有64 位 LabVIEW与数据流中间表示(DFIR)。DFIR立即被用于创建更先进形式的循环不变代码移出,常数合并,死码删除以及不可执行编码删除。2009新语言的特点,例如并行循环,都是基于DFIR创建。最终,在LabVIEW 2010,DFIR提供了新的编译器优化,例如代数重组,公共子表达式消除,循环展开,以及subVI直接插入。此正式版本也
8、包括在LabVIEW编译器链中采用了低阶虚拟机(LLVM)。LLVM是一种开放源代码的编译器基本结构,广泛应用于工业生产。使用LLVM,新增了很多优化,例如指令调度,循环外提,指令组合,条件传播,以及一种更精密的寄存器分配程序。当今的编译器当对LabVIEW编译器的历史有了基本了解后,您现在可以探索现代LabVIEW的编译器了。首先,回顾高级的多种类型编译步骤概述,然后更加详细地浏览每一部分。一个VI编译的第一步是类传播算法。这复杂的一步是为了解析适于终端输入的隐含类型,并检测语法错误。在G编程语言所有可能的语法错误都在类传播算法这一步被检测。如果算法确定VI有效,编译继续。在类传播后,VI首
9、先被从结构图编辑器使用的模型转化为编译器使用的DFIR。一旦转化为DFIR,编译器对DFIR图执行几个变换,分解它 ,优化它,并使其为生成代码做好准备。很多编译器的优化例如,内嵌程序(inplacer)与丛聚程序被执行转化并在本步运行。在DFIR图标被优化与简化后,它被翻译成LLVM中间表示。对LLVM一些列的扫描被执行,通过中间表示来进一步优化并降低其阶次,最终变为机器码。类传播如先前提到的,类传播算法解析类型并检测程序错误。实际上,此算法包括如下几个方面的功能: 解析隐藏类型使其适于终端输入 解析subVI调用并确定其合法性 计算纵向 检验VI的周期 检测并报告语法错误此算法在您对VI进行
10、每个改动后运行,以确定VI是否仍然完好,因此,这步是否是“编译”的真正部分还存在少许争议。无论如何,它是LabVIEW编译链的一环,非常明显地相当于传统编译器的词法分析,句法分析,或者是语义分析。一个适于终端输入的简单例子是LabVIEW加法基元。如果您将两个整数相加,结果是整数,但是如果您将两个浮点数相加,结果是一个浮点数。类似的案例出现在符合类型的数据,例如阵列和簇。存在其它语言结构,例如对移位寄存器来说,有更复杂的输入规则。在加法基元的情况下,输出类型取决于输入类型,类型被叫做通过图表“传播”,这也是算法名字的由来。这个加法基元的例子也表明类传播算法的语法检查职能。假设您连接一个整数和一
11、个字符串到一个加法基元会发生什么?在这种情况下,将二者的值相加没有意义,所以类传播算法将其报告为一个错误并将VI标记为“坏的”,它会引起运行箭头中断。中间表示是什么与为什么在类传播确定VI是有效的,编译器继续并将VI转化成DFIR。一般来说在详细设计DFIR之前要考虑中间表示(IRs)。IR是由编译过程通过多阶段编辑过的用户程序的表示。IR的概念常见于现代编译文献并能应用于任何编程语言。请考虑一些例子。当今有多种流行的IRs。两种常见的例子是抽象语法树(AST)与三地址码。t0 - yt1 - 3t2 - t0 * t1t3 - xt4 - t3 + t2图 1. AST IR实例表 1.三地
12、址码 IR实例图 1显示了“x + y * 3”表达的 AST表示,而表1 显示了三地址码表示两种表示方式之间最明显的一处不同是AST是更高级的。它更类似于程序(C)的源表示而不是对象表示(机器码)。三地址码相比之下,是低级的并且更类似于汇编。不论高级或低级表示都有各自的优点。例如,语法分析,比如可靠性分析,对类似于AST的高级表示比类似于三地址码的低级表示更容易实现。其它的优化,例如寄存器分配或指令调度,一般用低级表示,比如三地址码来执行。因为不同的IR有不同的优势和劣势,所以很多编译器(包括 LabVIEW)会使用多种IR。在LabVIEW中,DFIR作为高级IR使用,而LLVM IR作为
13、低级IR使用。DFIR在LabVIEW中,作为高级表示的是 DFIR,它是分等级且基于图形的,其本身类似于G代码。如同G代码,DFIR也是由很多包含接线端的节点组成。每个接线端可以连接到其它接线端。一些节点,例如包含图表的循环,也可以相应地包含其它节点。图 2. LabVIEW G 代码与相应的DFIR 图表图2显示了一个简单的VI以及它的初步DFIR表示。当首次创建一个VI的DFIR图表时,它是G代码的直接翻译,DFIR图表的节点一般与G代码中的其它节点进行一对一的通信。随着编译的进行,DFIR节点有可能被移动或者分开,或者新的DFIR节点被加入。DFIR一个最关键的优势是它保留了G代码的固
14、有特性,如并行机制等。用三地址码表示的并行机制相比之下更难识别。DFIR为LabVIEW编译器提供了两个显著的优势。首先,DFIR从VI编译器的表示分离出编辑器。其次,DFIR能用作拥有多个前端和后端的编译器的公共端。以下是每一个优势的详细解读。DFIR图表从编译器表示分离出编辑器在DFIR出现之前,LabVIEW有一个单独的VI表示,由编辑器和编译器共享。这样阻止了编译器在编译过程中修改表示,这样一来,进行编译器优化就变得困难了。图 3. DFIR 提供一种构架,允许编译过程中优化您的代码图3显示了对应于刚才提到的VI的DFIR图表。此图表描述了编译器过程较靠后的部分,此时它已被几个变换分解
15、并优化过。您可以看到,这个图表与之前的图表看起来有很大的不同。例如: 分解变换已经移走了控制,指示,以及子VI节点,而用新的节点替代它们UIAccessor, UIUpdater, FunctionResolver和 FunctionCall。 循环不变式代码已从循环内将增量和乘法节点移出。 聚丛法在For 循环内部增加了YieldIfNeeded节点,可以使执行线程与其它竞争的工作项目共享执行。我们将会在后面的章节对变换进行更深入探讨。DFIR IR可以作为多个编译器前端与后端的公共端LabVIEW可以在数个不同的终端上工作,而其中一些终端与其它终端差别很大,例如,一台x86 台式 PC与一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NI LabVIEW 编译器:深层分析 编译器 深层 分析
限制150内