假设我们正在开发 LabVIEW 代码,用于监控局域网内任意时刻运行的 LabVIEW 实例数量。代码片段大致如下:
在这段代码中,TCP打开连接函数会在 1 秒后超时,循环总共执行 256 次。
上述代码的最坏执行时间约为256秒。在一台 Windows 7 四核电脑上实测,执行时间约为225秒。
我们通常会产生两个疑问:
有没有办法缩短执行时间?
能否利用所有可用 CPU 核心来提升性能?
答案都是:可以。下面说明如何实现。
从LabVIEW 2009开始,For 循环新增了迭代并行功能。
我们在代码中启用该功能并调试最优参数,最终将执行时间从225秒缩短到仅4秒。
启用 “迭代并行” 的步骤
使用菜单Tools >> Profile >> Find Parallelizable Loops工具,检查 For 循环是否可并行。
如果循环不可并行,消除迭代间的数据依赖。移位寄存器、反馈节点是最常见的数据依赖来源,尽量避免使用。
在本例中,我们将迭代无关代码与迭代相关代码分离。修改后,第一个 For 循环可并行,第二个因存在迭代依赖不可并行。
右键单击第一个 For 循环边框,选择Configure Iteration Parallelism(配置迭代并行)。
窗口中Number of generated parallel loop instances(生成的并行循环实例数)记为T,最大值可设为64。
不勾选Allow debugging(允许调试),保持Automatically partition iterations(自动分区迭代)选中。
勾选Enable loop iteration parallelism(启用循环迭代并行),确定后循环上会出现P端子。
为 P 端子创建控件,命名为 P。
下表为不同 P、T 组合的执行时间测试结果。
测试结果表
P 端子输入值 / 执行时间(秒)
表格
P输入 | T=2 | T=4 | T=8 | T=16 | T=32 | T=64 |
2 | 113.02 | 125.00 | 122.01 | 124.01 | 119.01 | 110.02 |
未接线(四核) | 100.03 | 61.01 | 58.01 | 61.02 | 61.01 | 53.78 |
4 | 115.02 | 60.00 | 60.00 | 54.02 | 49.00 | 54.01 |
8 | 114.01 | 62.00 | 28.01 | 28.02 | 31.00 | 28.07 |
16 | 102.03 | 58.01 | 26.01 | 15.01 | 14.01 | 14.02 |
32 | 100.01 | 57.01 | 30.00 | 15.01 | 6.04 | 7.01 |
64 | 123.00 | 62.99 | 29.01 | 15.01 | 7.01 | 3.07 |
128 | 122.00 | 58.00 | 29.01 | 15.00 | 7.01 | 4.02 |
256 | 118.01 | 59.01 | 30.01 | 14.01 | 7.03 | 4.08 |
关键观察
当P > T时,执行时间与P=T基本一致。
P 不接线时,LabVIEW 会自动按 CPU 核心数分配线程:双核→2,四核→4。
结论
T(生成的并行循环实例数):编译时生成的线程数量。
P端子:运行时实际使用的线程数(取自 T 生成的线程池)。
P 端子不接线时,LabVIEW 自动按目标机器 CPU 核心数分配线程。
P超过64无性能提升(T 最大仅支持 64)。
若代码体积大,T=64 可能占用大量内存,此时应降低 T。
本例因包含 TCP 等待延迟,64 线程可真正并行,提升极显著;无延迟的纯CPU计算,提升通常不超过 2~4 倍,甚至因线程调度开销性能下降。
本例中 64 线程达到最佳性能(3 秒),但并非所有场景都如此,受内存、代码无延迟、CPU 核心数限制。
若循环内无等待延迟,建议 P 端子不接线,由 LabVIEW 自动最优分配。