文档介绍:LabVIEW 程序的内存优化 2 - 子 VI 的优化
1. 子 VI 参数的缓存重用
数据在子 VI 间传入传出,如果程序设计的好,可以做到缓存重用,使得数据在主 VI 和子 VI 中都不发生拷贝,提高程序的效率。
我的数据拷贝一份再传到子 VI 中去。
例如图3中的程序,它所调用的子 VI 就是图2中那个 VI。由于与它的第一种输入参数相连的是一种常量,而常量的值是不能被变化的。因此 LabVIEW 要把这个常量的值复制一份,再传到子 VI 中去,以保证子 VI 中的运算节点可以做缓存重用。
图3:父 VI 中的数据拷贝
如果图3中的父 VI,她也使用与接线器相连的输入控件为子 VI 提供输入参数,则 LabVIEW 会懂得,父 VI 的这个数据是由再上一层 VI 提供的,这里也不需要做数据拷贝。这样,这个 VI 就也做到了缓存重用。设计合理,参数在传递多种深度后都不需要开辟新内存的。
从上面的阐明中,还可以发现一种问题。就是,有时候子 VI 的改动,会影响父 VI 的行为,例如与否为传入子 VI 的数据做个拷贝等等。有时候我们发现改动了一种子 VI,它的父 VI 也需要重新保存,就是由这个因素引起的。
2. 输入输出参数的排布
在子 VI 的程序框图上,不管代码有多复杂,有多少嵌套的构造,控件终端最佳按照这样的方式排布:所有输入参数(控制型控件的终端)都放在代码的最左端排成一列;所有的输出参数(显示型控件的终端)都放在代码。例如图4中的代码的风格就比较好。
图4:控件终端整洁的排列在程序框图左右两端
这一方面是为了保证程序有良好的可读性。我们在阅读 LabVIEW 代码的时候总是按照从左到右的顺序,所有的参数都排布在一起,我们就可以以数据线为线索,容易的找的数据被读写的地方。另一方面,这种风格的 VI,在效率上也比较优化。
对于一种输入参数(控制型控件的终端),如果把它放程序代码的最左侧,所有构造的外面,程序在运营这个子VI之前,就可以得到这个参数的确切值了。
但是,如果这个终端是在代码的某个构造中的,在某一构造的内部,那么LabVIEW必须在运营到这一构造内部的时候,才可以去读这个参数的值,否则也许会引起逻辑上的错误。例如说,一种控制型控件的终端是在一种循环的内部,开始时它的值是x。在运营到第n次循环之前,这个终端相应的前面板上的控件被人改为一种新的数值y。那么逻辑上,在执行第n次循环之前,每次用到这个参数时,它的值要保持为x,而在第n次循环的时候,又要使用它的新值y。这样的数据所在的内存,LabVIEW 显然是不能将其重用的,否则下次循环再读它的时候,数据就不对的了。
如果这个终端是在所有构造之外,LabVIEW 则可以根据数据线的链接,明确的判断出在某一节点执行完之后,程序再也不需要用到这个参数的值了,那么 LabVIEW 就可以重用它所在的内存,以避免开辟新内存,拷贝数据等操作。这样就提高了程序的内存效率。
对于一种输出参数(显示型控件的终端),如果它位于某个条件构造的内部,LabVIEW 就要考虑,程序有也许执行不到这个条件。LabVIEW 就会多添加某些代码来解决这种状况,当 VI 没有运营到这个条件时,要给输出参数准备一种默