首页 理论教育LabVIEW2012中文版虚拟仪器入门精通

LabVIEW2012中文版虚拟仪器入门精通

【摘要】:本部分将讨论影响VI执行速度的因素并提供了一些取得VI最佳性能的编程技巧。将VI结构化可提高VI的运行性能,从而在一次调用中即传输大量数据而不是通过多次调用传输少量数据。多数应用程序中,异步显示可在不影响显示结果的前提下显著提高执行速度。如控件被隐藏,LabVIEW的数据传递速度将提高,但由于控件可随时被显示,LabVIEW仍需更新控件。LabVIEW随后便把数据发送到执行线程。

尽管LabVIEW可编译VI并生成快速执行的代码,但对于一部分时间要求苛刻的VI来说,其性能仍有待提高。本部分将讨论影响VI执行速度的因素并提供了一些取得VI最佳性能的编程技巧。

检查以下项目以找出性能下降的原因:

输入/输出(文件、GPIB、数据采集、网络)

屏幕显示(庞大的控件、重叠的控件、打开窗口过多)

内存管理(数组和字符串的低效使用,数据结构低效)

其他因素,如执行系统开销和子VI调用系统开销,但通常对执行速度影响极小。

1.输入/输出

输入/输出(I/O)的调用通常会导致大量的系统开销。输入/输出调用所占用的时间比运算更多。例如,一个简单的串口读取操作可能需要数微秒的系统开销。由于I/O调用需在操作系统的数个层次间传输信息,因此任何用到串口的应用程序都将发生该系统开销。

解决过多系统开销的最佳途径是尽可能减少I/O调用。将VI结构化可提高VI的运行性能,从而在一次调用中即传输大量数据而不是通过多次调用传输少量数据。

例如,在创建一个数据采集(NI-DAQ)VI时,有两种数据读取方式可供选择。一种方式为使用单点数据传递函数,如AI Sample Channel VI,另一种方式为使用多点数据传递函数,如AI Acquire Waveform VI。如必须采集到100个点,可用AI Sample Channel VI和“等待”函数构建一个计时循环。也可用AI Acquire Waveform VI,使之与一个输入连接,表示需要采集100个点。

AI Acquire Waveform VI通过硬件计时器来管理数据采集,从而使数据采样更为高速精确。此外,AI Acquire Waveform VI的系统开销与调用一次AI Sample Channel VI,的系统开销大体相等,但前者所传递的数据却多得多。

2.屏幕显示

在前面板上频繁更新控件是最为占用系统时间的操作之一。这一点在使用图形和图表等更为复杂的显示时尤为突出。尽管多数显示控件在收到与原有数据相同的新数据时并不重绘,但图表显示控件在收到数据后不论其新旧总会重绘。如重绘率过低,最好的解决方法是减少前面板对象的数量并尽可能简化前面板的显示。对于图形和图表,可关闭其自动调整标尺、调整刻度、平滑线绘图及网格等功能以加速屏幕显示。

对于其他类型的I/O,显示控件均占用一部分固定的系统开销。图表等输入控件可将多个点一次传递到输入控件。每次传递到图表的数据越多,图表更新的次数便越少。如将图表数据以数组的形式显示,可一次显示多点而不再一次只显示一个点,从而大幅提高数据显示速率。

如设计执行时其前面板为关闭状态的子VI,则无须考虑其显示的系统开销。如前面板关闭则控件不占用绘制系统开销,因此图表与数组的系统开销几乎相同。

多线程系统中,可通过高级>>同步显示的快捷菜单项来设置是否延迟输入控件和显示控件的更新。在单线程系统中,本菜单项无效。然而,在单线程系统中打开或关闭VI的这个菜单项后,如把VI载入多线程系统,设置将同样生效。

在默认状态下,输入控件和显示控件均为异步显示,即执行系统将数据传递到前面板输入控件和显示控件后,数据可立即执行。显示若干点后,用户界面系统会注意到输入控件和显示控件均需要更新,于是重新绘制以显示新数据。如执行系统试图快速地多次更新控件,用户可能无法看到介于中间的更新状态。

多数应用程序中,异步显示可在不影响显示结果的前提下显著提高执行速度。例如,一个布尔值可在1s内更新数百显次,每次更新并非人眼所能察觉。异步显示令执行系统有更多时间执行VI,同时更新速率也通过用户界面线程而自动降低。

要实现同步显示,可右键单击该输入控件或显示控件,从快捷菜单中选择高级>>同步显示,勾选该菜单项的复选框

注意

同步显示仅在有必要显示每个数据值时启用。在多线程系统中使用同步显示将严重影响其性能。

延迟前面板更新属性可延迟所有前面板更新的新请求。

调整显示器设置和前面板控件也可提高VI的性能。可将显示器的色深度和分辨率调低,并启用硬件加速。关于硬件加速的详细信息,参见所使用操作系统的相关文档。使用来自经典选板而不是新式的控件也可提高VI性能。

3.在应用程序内部传递数据

在LabVIEW的应用程序中传递数据的方法有许多种。常见的数据传递方法,按其效率排序。

(1)连线:可传递数据并使LabVIEW最大程度地控制性能,令性能最优化。数据流语言只有一个写入器及一个或多个读取器,因而传输速度最快。

(2)移位寄存器:适于需在循环中保存或反馈时使用。移位寄存器通过一个外部写入器及读取器和一个内部写入器及读取器进行数据传递。有限的数据访问令LabVIEW的效率最大化。

(3)全局变量和函数全局变量:全局变量适于简单的数据和访问。大型及复杂的数据可用全局变量读取和传递。函数全局变量可控制LabVIEW返回数据的多寡。

控件、控件引用和属性节点可作为变量使用。尽管控件、控件引用和属性节点皆可用于VI间的数据传递,但由于其必须经由用户界面,因此并不适于作为变量使用。一般仅在进行用户界面操作或停止并行循环时才使用本地变量和“值”属性。

用户界面操作通常速度较慢。LabVIEW将两个值通过连线在数纳秒内完成传递,同时用数百微秒到数百毫秒不等的时间绘制一个文本。例如,LabVIEW可把一个100k的数组通过连线在0ns到数微秒内将其传递。绘制该100k数组的图形需要数十毫秒。由于控件有其用户界面,故使用控件传递数据将产生重绘控件的副作用,令内存占用增加,VI性能降低。如控件被隐藏,LabVIEW的数据传递速度将提高,但由于控件可随时被显示,LabVIEW仍需更新控件。

多线程对用户界面操作的影响。完成用户界面操作一般占用内存更多,其原因在于LabVIEW需将执行线程切换到用户界面线程。例如,设置“值”属性时,LabVIEW将模拟一个改变控件值的用户,即停止执行线程并切换到用户界面线程后对值进行更改。接着,LabVIEW将更新用户界面的数据。如前面板打开,还将重绘控件。LabVIEW随后便把数据发送到执行线程。执行线程位于称作传输缓冲区的受保护内存区域内。最后LabVIEW将切换回执行线程。当执行线程再次从控件读取数据时,LabVIEW将从传输缓冲区寻找数据并接收新的值。

将数据写入本地或全局变量时,LabVIEW并不立即切换到用户界面线程。而是把数值写入传输缓冲区。用户界面将在下一个指定的更新时间进行更新。变量更新可能在线程切换或用户界面更新前多次进行。原因在于变量仅可在执行线程中运算。(www.chuimin.cn)

函数全局变量不使用传输缓冲区,因此可能比一般的全局变量更高效。函数全局变量仅存在于执行线程中,除非需在打开的前面板上显示其数值,一般无需使用传输缓冲区。

4.并行程序框图

有多个程序框图并行运行时,执行系统将在各程序框图间定期切换。对于某些较为次要的循环,等待(ms)函数可使这些次要循环尽可能少地占用时间。

例如,考虑图12-2所示的程序框图。

有两个并行的循环。第一个循环用于采集数据且需要尽可能频繁地执行。第二个循环用于监测用户的输入。由于程序编写的原因,这两个循环使用同等长度的时间。可令检测用户操作的循环在一秒内运行数次。

事实上,令该循环以低于每半秒执行一次的频率执行同样可行。在用户界面循环中调用等待(ms)函数可将更多执行时间分配给另一个循环,如图12-3所示。

978-7-111-40983-0-Chapter12-2.jpg

图12-2 并行执行的程序框图实例

978-7-111-40983-0-Chapter12-3.jpg

图12-3 改进后的并行执行程序

5.子VI系统开销

调用子VI需占用一定数量的系统开销。与历时数毫秒至数十毫秒的I/O系统开销和显示系统开销相比,该系统开销极为短暂(数十微秒)。但是,该系统开销在某些情况下会有所增加。例如,在一个循环中调用子VI达10000次后,其系统开销将对执行速度带来显著影响。此时,可考虑将循环嵌入子VI。

减少子VI系统开销的另一个方法是,将子VI转换为子程序,即在文件>>VI属性对话框的顶部下拉菜单中选择执行,再从优先级下拉菜单中选择子程序。但这样做也有其代价。子程序无法显示前面板的数据、调用计时或对话框函数,也无法与其他VI多任务执行。子程序通常最适于不要求用户交互且任务简短、执行频率高的VI。

6.循环中不必要的计算

如计算在每次循环后的结果相同,应避免将其置于循环内。正确的做法是将计算移出循环,将计算结果输入循环。

例如,考虑图12-4所示的程序框图。

循环中每次除法计算的结果相同,故可将其从循环中移出以提高执行性能。如图12-5所示。

978-7-111-40983-0-Chapter12-4.jpg

图12-4 包含不必要计算的程序框图

978-7-111-40983-0-Chapter12-5.jpg

图12-5 改进后的程序框图

如图12-6所示的程序框图中,如果全局变量的值不会被这个循环中另一个同时发生的程序框图或VI更改,那么每次在循环中运行时,该程序框图将会由于全局变量的读写而浪费时间。

如不要求全局变量在这个循环中被另一个程序框图读写,可使用图12-7所示的程序框图。

978-7-111-40983-0-Chapter12-6.jpg

图12-6 不必要的全局变量的读取

978-7-111-40983-0-Chapter12-7.jpg

图12-7 改进后的对全局变量的读取

注意

移位寄存器必须将新的值从子VI传递到下一轮循环。图12-8所示的程序框图显示了一个常见于初学者的错误。由于未使用移位寄存器,该子VI的结果将永远无法作为新的输入值返还给子VI。

978-7-111-40983-0-Chapter12-8.jpg

图12-8 错误的改进方法