CSM MassData Support Addon
概述
CSM MassData参数支持提供了一种高效的参数传递机制,专门用于在CSM中传递大量数据,例如:数组、波形数据等。也用于无损地传递复杂数据类型。
设计目标
MassData Addon旨在解决以下问题:
- 大数据传递效率:直接传递大数组会导致内存拷贝开销
- 数据完整性:确保复杂数据类型的无损传递
- 内存管理:自动化的内存管理,避免内存泄漏
- 跨模块共享:多个CSM模块间高效共享数据
主要特点
- 高效传输:通过使用内存高效的引用机制而非直接传输数据,从而提高了参数传递的效率和性能
- 无损传输:CSM MassData数据传输是完全无损的,适合传递复杂数据类型
- 共享缓存:同一应用程序内的所有CSM模块共享相同的MassData缓冲区空间
- 循环缓冲区:内部使用循环缓冲区机制,当缓冲区满时,新数据将从开始位置覆盖旧数据
- 类型支持:支持多种数据类型,包括数组、波形数据等复杂数据类型
- 调试支持:提供了调试工具,用于监控缓存使用情况,帮助优化配置
工作原理
MassData不直接传递数据本身,而是:
- 将数据写入共享的循环缓冲区
- 返回数据在缓冲区中的起始地址和大小
- 接收方通过地址和大小从缓冲区读取数据
- 自动管理缓冲区空间,旧数据被新数据覆盖
与HEXSTR的对比
| 特性 | MassData | HEXSTR |
|---|---|---|
| 适用数据量 | 大数据(>1KB) | 小数据(<1KB) |
| 性能 | 高(引用传递) | 中(编码解码开销) |
| 内存开销 | 低(共享缓冲区) | 高(字符串拷贝) |
| 实现复杂度 | 中 | 低 |
| 调试难度 | 中(需工具查看) | 低(直接查看字符串) |
| 适用场景 | 数组、波形、图像 | 小簇、配置数据 |
使用场景选择
使用MassData的场景:
- 数据量 > 1KB
- 频繁传递数据
- 需要传递数组、波形
- 性能要求高
使用HEXSTR的场景:
- 数据量 < 1KB
- 偶尔传递数据
- 需要传递小簇
- 调试友好性重要
Massdata参数类型
CSM Massdata定义的参数类型为<MassData>,可以通过CSM - Argument Type.vi获取。
参数格式
MassData参数有两种格式:
格式1:带数据类型
<massdata>Start:8057;Size:4004;DataType:1D I32
使用CSM - Convert MassData to Argument With DataType.vim生成。
优点:
- 包含数据类型信息
- 接收方可以验证类型
- 便于调试
适用场景:
- 数据类型可能变化
- 需要类型验证
- 多种数据类型混合
格式2:不带数据类型
<massdata>Start:8057;Size:4004
使用CSM - Convert MassData to Argument.vim生成。
优点:
- 参数字符串更短
- 性能略高
适用场景:
- 数据类型固定
- 不需要类型验证
- 性能敏感
参数组成
- **
**: 参数类型标记 - Start: 数据在缓冲区中的起始地址(字节)
- Size: 数据大小(字节)
- DataType: 数据类型描述(可选)
核心API
编码API
CSM - Convert MassData to Argument.vim
- 将数据转换为MassData参数(不带类型)
- 多态VI,自动适应输入类型
- 返回参数字符串
CSM - Convert MassData to Argument With DataType.vim
- 将数据转换为MassData参数(带类型)
- 多态VI,自动适应输入类型
- 返回参数字符串和类型信息
解码API
CSM - Convert Argument to MassData.vim
- 将MassData参数转换回数据
- 多态VI,自动适应输出类型
- 从缓冲区读取数据
配置API
CSM - Config MassData Parameter Cache Size.vi
- 配置缓冲区大小
- 必须在使用MassData前调用
- 默认大小可能不满足需求
监控API
CSM - MassData Update Status Indicator.vi
- 更新UI状态指示器
- 显示缓冲区使用情况
- 辅助调试和优化
CSM - MassData Data Type String.vi
- 从参数中提取数据类型信息
- 用于类型验证
缓冲区管理
缓冲区配置
缓冲区大小直接影响性能和功能:
配置原则:
- 根据最大数据量设置
- 留有余量(建议2-3倍)
- 考虑并发数据数量
- 平衡内存和性能
配置示例:
// 设置10MB缓冲区
CSM - Config MassData Parameter Cache Size.vi
Size: 10 * 1024 * 1024 // 10MB
循环覆盖机制
当缓冲区满时:
- 新数据从头开始写入
- 覆盖最旧的数据
- 自动更新地址索引
注意事项:
- 确保数据被使用前不被覆盖
- 监控缓冲区使用率
- 及时处理接收到的数据
监控缓冲区状态
使用调试工具监控:
- 使用
CSM - MassData Update Status Indicator.vi - 或使用CSM Tools中的MassData Cache Status Viewer
- 查看缓冲区使用率
- 识别潜在问题
应用场景
场景1:数据采集系统
需求:
- DAQ硬件连续采集数据
- 采集速率高,数据量大
- 需要传递给处理模块
方案:
// 采集模块
DAQ: Acquire >> {
Acquire Data -> Waveform Array
// 转换为MassData
CSM - Convert MassData to Argument.vim
Data: Waveform Array
→ Arguments: <massdata>...
// 发送给处理模块
API: ProcessData >> Arguments -> ProcessModule
}
// 处理模块
API: ProcessData >> {
// 解码MassData
CSM - Convert Argument to MassData.vim
Arguments: <massdata>...
→ Data: Waveform Array
// 处理数据
Process Data...
}
优势:
- 高效传递大波形数据
- 不阻塞采集循环
- 处理模块可以异步处理
场景2:图像处理
需求:
- 相机捕获图像
- 图像数据量大(MB级)
- 多个模块需要处理
方案:
// 相机模块
Camera: Capture >> {
Capture Image -> 2D Array
// 转换为MassData
CSM - Convert MassData to Argument With DataType.vim
Data: Image Array
→ Arguments: <massdata>...Start:xxx;Size:yyy;DataType:2D U8
// 广播给多个处理模块
ImageReady >> Arguments -> <broadcast>
}
// 处理模块1:显示
ImageReady Subscription >> {
CSM - Convert Argument to MassData.vim
→ Image
Display Image...
}
// 处理模块2:分析
ImageReady Subscription >> {
CSM - Convert Argument to MassData.vim
→ Image
Analyze Image...
}
优势:
- 一次采集,多次使用
- 共享缓冲区,节省内存
- 高效广播机制
场景3:文件数据传递
需求:
- 读取大文件
- 传递给多个模块
- 减少文件IO
方案:
// 文件读取模块
API: LoadFile >> {
Read File -> Data Array
CSM - Convert MassData to Argument.vim
→ Arguments
Response: Arguments
}
// 使用模块
API: Start >> {
// 同步调用,获取数据
API: LoadFile -@ FileModule
// Response中包含MassData参数
CSM - Convert Argument to MassData.vim
→ Data Array
Process Data...
}
优势:
- 文件只读取一次
- 多个模块高效共享
- 减少IO开销
场景4:生产者-消费者模式
需求:
- 生产者连续产生数据
- 消费者处理数据
- 解耦生产和消费
方案: 在非CSM框架中也可以使用MassData:
// 生产者循环
Loop {
Produce Data -> Array
CSM - Convert MassData to Argument.vim
→ MassData String
Enqueue(Queue, MassData String)
}
// 消费者循环
Loop {
Dequeue(Queue) -> MassData String
CSM - Convert Argument to MassData.vim
→ Array
Consume Data...
}
优势:
- 不限于CSM框架
- 高效队列传递
- 解耦生产消费
最佳实践
1. 缓冲区大小设置
建议:
// 计算所需大小
Max Single Data Size = 1 MB
Concurrent Data Count = 5
Safety Factor = 2
Buffer Size = Max Single Data Size × Concurrent Data Count × Safety Factor
= 1 MB × 5 × 2 = 10 MB
注意事项:
- 启动时尽早设置
- 考虑峰值需求
- 监控实际使用情况
- 必要时动态调整
2. 数据生命周期管理
原则:
- 尽快使用接收到的数据
- 不要长时间持有MassData参数
- 必要时拷贝数据到本地
示例:
API: ProcessData >> {
// 立即解码
CSM - Convert Argument to MassData.vim
→ Data
// 如果需要保存,立即拷贝
If (Need Save) {
Local Copy = Data
}
// 处理数据
Process Data...
}
3. 错误处理
检查点:
- 编码前检查数据有效性
- 解码时验证参数格式
- 处理缓冲区满的情况
- 记录异常到全局日志
示例:
// 编码时
If (Data Valid?) {
CSM - Convert MassData to Argument.vim
} else {
// 处理无效数据
Log Error...
}
// 解码时
Try {
CSM - Convert Argument to MassData.vim
} Catch {
// 处理解码错误
Log Error...
Use Default Data...
}
4. 性能优化
技巧:
- 批量传递:一次传递多个数据项而不是多次单项传递
- 异步处理:使用异步消息,避免阻塞
- 选择合适格式:性能敏感时使用不带类型的格式
- 监控使用:定期检查缓冲区使用率
5. 调试技巧
方法:
- 使用状态指示器:
CSM - MassData Update Status Indicator.vi - 使用CSM工具:
- 打开MassData Cache Status Viewer
- 实时监控缓冲区
- 日志记录:
// 记录MassData参数 Log: <massdata>Start:xxx;Size:yyy - 类型验证:
CSM - MassData Data Type String.vi → Expected Type?
6. 跨框架使用
MassData可在非CSM框架中使用:
适用场景:
- 生产者-消费者架构
- 队列传递大数据
- 状态机间通讯
注意事项:
- 仍需调用配置API
- 手动管理数据生命周期
- 确保接收方及时处理
常见问题
Q1: 缓冲区满了怎么办?
现象:新数据覆盖了还未使用的旧数据
解决方案:
- 增大缓冲区
- 加快数据处理速度
- 减少并发数据量
- 使用本地拷贝保存重要数据
Q2: 如何选择是否带类型?
带类型适合:
- 数据类型不固定
- 需要运行时类型检查
- 调试阶段
不带类型适合:
- 数据类型固定
- 性能要求高
- 生产环境
Q3: MassData vs 队列传递?
MassData优势:
- 与CSM消息集成
- 自动内存管理
- 支持广播
队列优势:
- 更灵活的流控
- 可以缓冲多个数据
- 不限于大数据
选择建议:
- CSM框架内:优先MassData
- 需要流控:使用队列
- 可以结合:队列传MassData参数
Q4: 性能瓶颈在哪里?
潜在瓶颈:
- 缓冲区过小导致频繁覆盖
- 数据拷贝(编码/解码时)
- 字符串操作开销
优化方向:
- 合理配置缓冲区
- 减少不必要的数据拷贝
- 使用不带类型的格式
示例范例
Overview
Massdata 参数用于在 CSM 框架中传递大量数据,例如:数组、波形数据等。也用于无损的传递复杂数据类型数据等场景。本范例用于展示CSM API参数中支持的MassData参数格式。
Introduction
本范例中模拟产生了两组数据:一组是I32数组数据,一组是波形数据,并将这两组数据转换为massdata 参数。
CSM的参数中支持的MassData参数格式如下:
<massdata>Start:8057;Size:4004;DataType:1D I32
每个部分的含义如下:
-
: 表示这是一个 MassData 参数。 - Start:MassData 数据在内存中的起始地址。
- Size:MassData 数据的大小(字节数)。
- DataType:(optional) MassData 数据的类型, 选择的打包函数不同,可以不包含该部分。
Steps
- Step1: I32数组数据, 此部分选择的打包函数为
CSM - Convert MassData to Argument With DataType.vim,因此包含DataType部分。- step1.1: 构造原始数据,在实际程序中来源与硬件采集、数据接收等情况。
- step1.2: 调用
CSM - Convert MassData to Argument With DataType.vim,将原始数据转换为massdata 参数。可以在前面板查看转换后的参数格式。 - step1.3: 使用CSM - MassData Data Type String.vi 获取MassData 参数字符串中的数据类型。
- step1.4: 使用CSM - Argument Type.vi 获取CSM参数标签,在这里是
。 - step1.5: 将 CSM massdata 参数转换回原始数据,可以在前面板查看转换后的数据,应该与原始数据完全匹配。
- Step2: 波形数据, 此部分选择的打包函数为
CSM - Convert MassData to Argument.vim,因此不包含DataType部分。- step2.1: 构造原始数据,在实际程序中来源与硬件采集、数据接收等情况。
- step2.2: 调用
CSM - Convert MassData to Argument.vim,将原始数据转换为massdata 参数。可以在前面板查看转换后的参数格式,选择这个打包函数,不包含DataType部分。 - step2.3: 使用CSM - Argument Type.vi 获取CSM参数标签,在这里是
。 - step2.4: 将 CSM massdata 参数转换回原始数据,可以在前面板查看转换后的数据,应该与原始数据完全匹配。
查看massdata缓存状态 (2. Show MassData Cache Status in FP.vi)
Overview
Massdata 使用一个后台环形队列来缓存数据,队列的大小可以在CSM API参数中配置。本范例用于展示如何查看MassData缓存状态。
Introduction
MassData 提供了一个帮助函数 CSM - MassData Update Status Indicator.vi,用于查看MassData缓存状态。本范例展示了如何使用这个函数。
Steps
- step1: 使用 CSM - Config MassData Parameter Cache Size.vi 设置缓存大小,可以在界面直观的看到这个设置是生效的。
- step2: 每次循环中,构造一组新的数据。
- step3: 使用 CSM MassData 的API对数据进行打包解包,模拟实际程序中的使用情况。
- step4: 使用 CSM - MassData Update Status Indicator.vi 更新垂直方向的UI界面缓存状态控件刷新。
- step5: 使用 CSM - MassData Update Status Indicator.vi 更新水平方向的UI界面缓存状态控件刷新。
- Step6:循环间隔,每个循环会重复 step3~step4。
- Step7:(optional) 可以通过本插件提供的 CSM-Tool 更加快捷的查看MassData缓存状态。
在非CSM框架中使用MassData(3. MassData in Non-CSM Framework.vi)
Overview
MassData 也可以在非CSM框架中使用。本范例用于展示如何在非CSM框架中使用MassData。
Introduction
通过一个生产者消费者框架的范例,展示了如何在非CSM框架中使用MassData。数据生产者负责生产数据,将数据打包为MassData 参数,并通过队列传输给数据消费者,数据消费者负责消费数据,将MassData格式的数据解包为原始数据,并进行处理。本范例展示了这个过程。
Steps
- step1: 使用 CSM - Config MassData Parameter Cache Size.vi 设置缓存大小。
- step2: 数据生产者循环
- step2.1: 构造原始数据,在实际程序中来源与硬件采集、数据接收等情况。
- step2.2: 调用 CSM - Convert MassData to Argument.vim 将原始数据转换为MassData参数。
- step2.3: 将转换后的MassData参数通过队列传输给数据消费者。
- step3: 数据消费者循环
- step3.1: 从队列中接收MassData 参数。
- step3.2: 调用 CSM - Convert Argument to MassData.vim 将massdata 参数转换为原始数据。
- step3.3: (optional) 使用 CSM - MassData Update Status Indicator.vi 更新UI界面缓存状态控件刷新。
在CSM框架中使用MassData(4. MassData in CSM.vi)
Overview
本范例用于展示如何在CSM框架中使用MassData。
Introduction
本范例通过一个生产者消费者的场景,展示了如何在CSM框架中使用MassData。
使用一个非CSM循环生成数据生产者负责生产数据,将数据打包为MassData 参数,并通过同步消息发送给作为数据消费者的CSM模块。本范例展示了这个过程。
Steps
- step1: 使用 CSM - Config MassData Parameter Cache Size.vi 设置缓存大小。
- step2: 数据生产者循环,这个循环不是CSM模块。
- step2.1: 构造原始数据,在实际程序中来源与硬件采集、数据接收等情况, 调用 CSM - Convert MassData to Argument.vim 将原始数据转换为MassData 参数。
- step2.2: 使用 CSM - Wait and Send Message for Reply.vi 将数据作为 API: Update Waveform 的参数,发送给CSM模块,并标记发送者为Producer。
- step2.3: 在 Generate 按钮为按下状态时,才发送数据。
- step2.4: (optional) 使用 CSM - MassData Update Status Indicator.vi 更新UI界面缓存状态控件刷新。
- step3: 数据消费者循环,这个循环是CSM模块,名称为”CSM”。
- step3.1: 在 API: Update Waveform 分支中,将收到的参数使用 CSM - Convert Argument to MassData.vim 将MassData 参数转换为原始数据并显示。
- step3.3: (Optional) 其他分支和 template 一致,没有修改。
- step4: 程序退出过程中,使用 CSM - Wait and Send Message for Reply.vi 发送同步消息“Macro: Exit” 给 CSM 模块,使CSM模块退出。
总结
CSM MassData Support Addon是处理大数据传递的首选方案:
核心优势
- 高性能:通过引用传递,避免大数据拷贝
- 易用性:自动内存管理,简化开发
- 灵活性:支持多种数据类型
- 可靠性:无损传递,完整性保证
使用建议
- 数据量 > 1KB:优先使用MassData
- 合理配置缓冲区:根据实际需求设置
- 及时处理数据:避免被覆盖
- 使用调试工具:监控使用情况
与其他方案对比
- vs HEXSTR:大数据时性能更优
- vs Queue:与CSM消息集成更好
- vs Global Variable:更安全,自动管理
更多资源
- GitHub: https://github.com/NEVSTOP-LAB/CSM-MassData-Parameter-Support
- 示例代码:参考本文档中的示例范例
- 调试工具:使用CSM Tools中的MassData Cache Status Viewer
通过合理使用MassData Addon,可以构建高效、可靠的数据密集型CSM应用。