LabVIEW性能和内存管理 1

本文介绍LabVIEW性能和内存管理的几个建议

目的:

了解LabVIEW执行系统

学习通过以下方法提高性能:

减少数据拷贝

减少总体内存使用量

了解VI执行属性

LabVIEW 执行系统:执行系统是LabVIEW的一部分,负责实际运行代码。

启用自动并行,这是LabVIEW特有的,而其他语言需要手动线程管理。

工作方式类似于线程池

作业队列:从队列中提取作业的一组线程;作业(“队列元素”)是要执行的VI代码片段。

每个执行系统一个队列:用户界面、标准、I / O工具、数据采集、其他1、

其他2、定时循环

每个执行系统都有多个线程。异常:UI只有一个线程。

这是执行系统如何工作的一个LabVIEW模型。对于每个执行系统(这里显示了三个),我们创建一个队列。放在队列上的数据表示要运行的已编译的VI代码片段。当VI的一部分准备好运行时,它被放到执行系统系统队列中。

每个执行系统都有一个或多个线程。每个线程都有一个循环,从队列中提取元素并执行该元素的代码。UI线程只有其中一个线程,但其他执行系统有多个线程共享相同的队列。当VI上的代码并行运行时,它是由其执行系统的不同线程处理的。

labview mysql列数不一致_LabVIEW

LabVIEW聚类算法

除了操作系统的抢占式多任务处理,LabVIEW还采用了协作式多任务处理系统。在编译过程中,LabVIEW分析VIs来定位可以在所谓的簇中一起执行的节点组。每个优先级和执行系统组合都有一个运行队列数据结构,该结构保留了哪些块可以一起运行。当执行系统激活一个线程时,执行系统从运行队列中检索并执行一个集群。当执行系统完成执行时,它将满足输入条件的额外块存储在运行队列上。这允许在任何可用的执行线程中执行框图。如果框图包含足够的并行性,它可以在所有线程中同时执行。

LabVIEW不会永久地将代码块分配给特定的线程。下次运行VI时,LabVIEW可能会使用不同的线程执行一个集群。

每个集群产生一段可以由LabVIEW安排的代码。在一个集群中,LabVIEW没有提供并行性。在集群之间,LabVIEW可以使用它的执行系统进行多任务处理。

labview mysql列数不一致_labview mysql列数不一致_02

LabVIEW聚类算法

labview mysql列数不一致_labview mysql列数不一致_03

上面所示的块表示框图的开始和结束。当两个For循环执行时,群集处于“休眠”状态,并被“唤醒”以完成VI(两个除法函数)。

为VI生成的代码假定存在LabVIEW执行系统。每个集群在VI的数据空间中都有一个记录,称为QElement。QElement可以放置在一个名为“runQ”的队列中,LabVIEW执行系统使用该队列来调度相关的代码部分。

通常,LabVIEW代码中的节点在继续之前必须等待一些东西。例如,队列或SubVIs可能正在被另一个线程使用,或者您可能在调试时进行单步操作。在这些情况下,VI代码的队列元素将被放入等待队列中,由它所等待的对象处理。在将VI代码放入等待队列后,它返回到运行它的执行系统线程,以便运行另一段代码。这被称为合作多任务处理。当等待队列上的代码段准备再次运行时,它将从等待队列中取出,然后放回到执行系统队列中。最终(可能是立即)该队列元素将再次从执行队列中取出并运行。

有时VIs会自动停止执行,以便允许其他代码运行。这可以防止长循环占用所有的执行时间。当发生这种情况时,VI代码只是返回到执行系统,并带有立即将其放回队列的指令。在其他代码有机会运行之后,这段VI代码将再次从队列中取出并运行。

任何时候,当一段VI代码由于某种原因不得不休眠时,该代码的队列元素会跟踪它停止的位置,以便下次它被调度时可以从相同的地方开始。

有些节点有首选的执行系统。最常见的首选执行系统是UI线程。有些节点必须运行在UI线程上。例如,VI Server属性节点和VI Server调用节点和打开VI引用节点必须运行在UI线程中。(此限制不适用于用于访问DAQ、LV类或其他使用属性/调用节点的类型的属性/调用节点。)此外,每个VI都可以指定首选的执行系统。默认值是“Same as caller”,这意味着VI可以在任何执行系统中运行。

当一个节点想要运行但处于错误的执行系统中时,它会导致队列元素“进入睡眠状态”,然后在另一个执行系统中被唤醒。回想一下,这意味着代码将停止执行,并将自己放在它想要运行的执行系统的队列中。当另一个执行系统有时间时,它将把元素拉回队列并执行它。这种转换需要时间,因此可能会导致性能问题。

为了避免这种情况,应该尽量避免不必要的UI代码(如VI服务器属性),并对SubVIs使用“Same ascaller”。有两种情况下,可能想为VI使用特定的首选执行系统:

如果VI中有UI代码,那么该代码必须在UI线程中运行。当你使用“same as caller”时,你很可能会在执行系统中而不是UI线程中运行。这意味着VI必须切换执行系统才能进入UI线程。然后,因为VI必须返回到它开始时所在的同一个执行系统,然后才能返回到调用者,所以它必须切换回来。如果这发生在一个循环中,那么它会显著影响性能。如果您将VI标记为优先使用UI线程,那么调用者可以在调用之前切换到UI线程。这可能意味着切换只在循环前后发生,而不是每次都发生。

如果VI中有一个长期运行的高优先级循环,用于处理数据采集之类的任务,那么可以将该VI标记为在其他执行系统(仪器I/O、数据采集、其他1或其他2)中运行,这样它就不必与其他Vis竞争执行系统的时间。记住,如果你不是运行在实时操作系统上,你仍然需要担心操作系统调度程序。使用定时循环来控制优先级会更可靠,而在实时操作系统上这样做是确保代码以正确的优先级运行的最可靠方法。