LabVIEW程序的内存优化之子VI的优.docx

上传人:scccc 文档编号:14585231 上传时间:2022-02-09 格式:DOCX 页数:7 大小:283.33KB
返回 下载 相关 举报
LabVIEW程序的内存优化之子VI的优.docx_第1页
第1页 / 共7页
LabVIEW程序的内存优化之子VI的优.docx_第2页
第2页 / 共7页
LabVIEW程序的内存优化之子VI的优.docx_第3页
第3页 / 共7页
LabVIEW程序的内存优化之子VI的优.docx_第4页
第4页 / 共7页
LabVIEW程序的内存优化之子VI的优.docx_第5页
第5页 / 共7页
亲,该文档总共7页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《LabVIEW程序的内存优化之子VI的优.docx》由会员分享,可在线阅读,更多相关《LabVIEW程序的内存优化之子VI的优.docx(7页珍藏版)》请在三一文库上搜索。

1、LabVIEW 程序的内存优化 2 -子VI的优化1 .子VI参数的缓存重用数据在子VI间传入传出,如果程序设计的好,可以做到缓存重用,使得数 据在主VI和子VI中都不发生拷贝,提高程序的效率。我们先来看一下图1所示的 VI o打开 ToolProfileShow BufferAllocations工具查看一下这个 VI中内存分配的情况,会发现在代码的加法函 数处有一个黑点。这个黑点说明程序在这里有分配了一块内存,这个内存是用来存储加法运算结果的。sFile Edit View Project Operate Lools Window Help1|“ Ipphcatian FontPJjmer

2、icNumeric 2Numeric 3图1:控件不与接线器相连时,加法处有内存分配为什么加法函数在这里不做缓存重用呢 ?利用其中一个加数的内存空间来保 存计算结果当这个VI运行的时候,图2中,加数Numeric的数据是由VI前面板的 控件提供的。如果用户不修改控件的值,每次VI运行,这个数值应该是保持不 变的。如果加法函数在这里做缓存重用, 加数或者说它对应的控件中的数据, 就 会在加法运算执行后被修改。这样程序就会出现逻辑上的错误。所以把一个这样的控件联在 LabVIEW的运算节点上,运算节点是不能重 用控件的数据内存的。同样的道理,链接一个常量到运算节点上,节点同样不能 做缓存重用。在子

3、 VI中,没有连到接线器上的输入控件就相当与一个常量。|但是,如果我们让 VI上的控件与 VI的接线器(Connector Pane心目连,情 况就不一样了。如图2所示,把三个控件连到接线器上,程序中加法节点上那个 黑点就消失了,不再为运算结果分配新的内存。I j图2:控件不与接线器相连时,加法处有内存分配这是因为,当输入控件与接线器连接后,LabVIEW就认为这个输入值应当是由子VI的调用者(父VI)提供的:连到接线器上,逻辑上,这个输入控件就 不再是常量,而是一个输入变量了。既然是输入变量,子VI不需要记住输入的 数据供下次调用时使用,因此可以把新产生的数据放在输入参数所在的内存,做到缓存

4、重用。你可能在想,这个输入参数的内存不一定可以被修改吧,万一它的数据还要在父VI中被其它节点使用呢?子VI是不需要考虑这点的,输入数据的数据被修改肯定是安全的, 这一点 是由父VI来保证的。如果输入数据不能被修改,父 VI会把传入的数据拷贝 一份再传到子VI中去。比如图3中的程序,它所调用的子 VI就是图2中那个VI。由于与它的第一 个输入参数相连的是一个常量,而常量的值是不能被改变的。所以LabVIEW要 把这个常量的值复制一份,再传到子 VI中去,以保证子 VI中的运算节点可 以做缓存重用。图3:父VI中的数据拷贝如果图3中的父VI,他也使用与接线器相连的输入控件为子VI提供输入参数,则L

5、abVIEW会知道,父 VI的这个数据是由再上一层 VI提供的,这 里也不需要做数据拷贝。这样,这个 VI就也做到了缓存重用。设计合理,参数 在传递多个深度后都不需要开辟新内存的。从上面的说明中,还可以发现一个问题。就是,有时候子VI的改动,会影响父VI的行为,比如是否为传入子 VI的数据做个拷贝等等。有时候我们发 现改动了一个子 VI,它的父VI也需要重新保存,就是由这个原因引起的。2 .输入输出参数的排布在子VI的程序框图上,不论代码有多复杂,有多少嵌套的结构,控件终端 最好按照这样的方式排布:所有输入参数(控制型控件的终端)都放在代码的最左端排成一列。所有的输出参数(显示型控件的终端)都

6、放在代码。比如图4中的代 码的风格就比较好。图4:控件终端整齐的排列在程序框图左右两端这首先是为了保证程序有良好的可读性。我们在阅读 LabVIEW代码的时 候总是按照从左到右的顺序,所有的参数都排布在一起,我们就可以以数据线为 线索,轻易的找的数据被读写的地方。其次,这种风格的 VI,在效率上也比较 优化。对于一个卒&入参数(控制型控件的终端),如果把它放程序代码的最左侧,所 有结构的外面,程序在运行这个子 VI之前,就可以得到这个参数的确切值了。但是,如果这个终端是在代码的某个结构中的,在某一结构的内部,那么 LabVIEW必须在运行到这一结构内部的时候,才可以去读这个参数的值,否则 可能

7、会引起逻辑上的错误。比如说,一个控制型控件的终端是在一个循环的内部, 开始时它的值是x。在运行到第n次循环之前,这个终端对应的前面板上的控件 被人改为一个新的数值y。那么逻辑上,在执行第n次循环之前,每次用到这个 参数时,它的值要保持为x,而在第n次循环的时候,又要使用它的新值 V。这 样的数据所在的内存,LabVIEW显然是不能将其重用的,否则下次循环再读它 的时候,数据就不正确了。如果这个终端是在所有结构之外,LabVIEW则可以根据数据线的链接,明 确的判断出在某一节点执行完之后,程序再也不需要用到这个参数的值了,那么LabVIEW就可以重用它所在的内存,以避免开辟新内存,拷贝数据等操作

8、。这样就提高了程序的内存效率。对于一个卒&出参数(显示型控件的终端),如果它位于某个条件结构的内部,LabVIEW就要考虑,程序有可能执行不到这个条件。 LabVIEW就会多添加一 些代码来处理这种情况,当VI没有运行到这个条件时,要给输出参数准备一个 默认值。把这个终端移到所有结构之外,就可以省去这部分LabVIEW自动添加上去的工作和,稍微提高一点效率:)3 .良好的数据流结构可以优化程序内存效率先看一个程序:图5:程序中没有必要的数据线分枝图5的程序只是一个演示,不必追究它到底实现了什么功能。图中的左半部 分是主VI,在这个VI中对输入的数组数据 Array进行了两次操作:一次使用 su

9、bVI “My Search:另一次使用了数组排序函数。图5的右半部分是subVI “My Search的程序框图。需要注意的是,主VI上Sort 1D Array函数那里有个黑点(这个黑店靠近黄 色方块的中心,这里看不太清楚,和图6对比一下,就可以发现了),说明这里做 了一次内存分配。这是因为 Array的数据被同时传递到了 “My Search “Sort 1D Array TW个节点进行处理。这两个操作可能会同时进行,LabVIEW 为了安全(两个操作对数据的改动不能相互影响,不能同时对一块内存进行读写),就必须为这两个节点准备两份数据在两份内存中。所以在“My Search和“Sort

10、 1D ArrayS”个节点中,如果一个节点用了原来 Array的内存,另一个节点就需要拷贝一份数 据给自己用。不过,如果看一下“My Search的程序框图,它其实没有对Array数据进行任 何改动,主VI完全没有比要给“SortlD Array 外辟一块新内存。我们只要对程 序稍作改动,就可以对此进行优化。图 6是改进后的程序:图6:符合数据流风格的主VI在改进后白程序中,Array数据首先传入subVI “My Search;然后又传出来, 继续传给“SortlD Array”函数。这样子看上去好像数据要多到子 VI中转一圈, 但实际上,由于子VI中Array输入输出是缓存重用的,实际上

11、相当于只是把数 组数据的引用传给了子 VI,效率是相当高的。而在主VI中,执行“Sort 1D Array 时,LabVIEW知道输入数据现在是这个节点专用的,改了他也是安全的,于是 也可以缓存重用。图六中,“Sort 1D Array上的那个小黑点就消失了。图6中的主VI ,它的优点首先是符合数据流的风格。一个主要的数据从左 到右,流经每个节点。这样的程序非常容易阅读和理解。LabVIEW也更容易对这样的代码进行优化,所以这样风格的程序通常效率也比较高。有的时候,利用LabVIEW的自动多线程特性,书写并行代码,对程序效 率有利。比如,程序中某一部分的代码需要较长时间的计算或者读写时间的情况。但是并不是任何时候并行执行都好。 并行书写的程序不易理解,容易出错,多线 程运行也会带来额外的开销。像图5、图6中的程序,数据量较大,但是并没有比 较耗时的运算操作,或数据读写操作,这样的程序,串行运算比并行效率更高。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1