假设我们正在开发 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 自动最优分配。