TinyBench 设计说明¶
设计动机¶
在嵌入式 SHM 节点上,数据和算法模块分散在不同的函数和全局变量中。外部 Agent 或用户无法在运行时发现:
- 当前有什么数据?采集结果存在哪里?
- 有什么工具可用?每个工具输入输出是什么?
TinyBench 解决这个问题——它是一个运行时可查询的命名注册表,把内存地址映射为名字,把不可见变为可发现。
核心设计决策¶
零拷贝¶
tiny_bench_put() 只存数据指针,不复制数据。调用者负责管理内存生命周期。这对嵌入式系统至关重要——避免在采集→处理→分析的每条路径上额外拷贝。
静态分配¶
所有表在 tiny_bench_init() 时清零,运行时零堆分配。配置宏(TINY_BENCH_MAX_DATA 等)决定表容量,编译时固定。
类型安全¶
每个数据槽和工具都带 tiny_type_t 类型标签。TinyOrch 在 step() 定义时做类型校验(src.type == tool.in_type),把错误暴露在执行之前。
数据槽 vs 工具注册表¶
| 数据槽 | 工具注册表 | |
|---|---|---|
| 管理什么 | 处理过程中的数据 | 可调用的处理函数 |
| 生命周期 | 动态(put / remove) | 静态(初始化时注册) |
| 查询 | list_data() | list_tools(), tool_info() |
| MQTT | BENCH,DATA | BENCH,TOOLS, BENCH,TOOL,name |
典型使用模式¶
1. 初始化 + 注册¶
系统启动时注册所有工具,这些工具在后续运行中不变:
tiny_bench_t bench;
tiny_bench_init(&bench);
tiny_bench_register_tool(&bench, "butterworth", fn_bw,
TINY_TYPE_F32_ARR, TINY_TYPE_F32_ARR);
tiny_bench_register_tool(&bench, "fft", fn_fft,
TINY_TYPE_F32_ARR, TINY_TYPE_CF32_ARR);
2. 运行时数据流¶
采集任务把数据放到工作台上,流程引擎读取并处理:
// 采集线程
tiny_bench_put(&bench, "raw_0", adxl_buffer, N * sizeof(float), TINY_TYPE_F32_ARR);
// 流程执行
void *data; size_t len; tiny_type_t type;
tiny_bench_get(&bench, "raw_0", &data, &len, &type);
// → 拿到 adxl_buffer 指针,零拷贝
3. Agent 远程查询¶
Agent 先查有什么工具和数据,再决定编排哪种流程。
设计约束¶
- 名称长度:
TINY_BENCH_NAME_LEN(默认 24),含\0 - 表满拒绝: 数据槽或工具数超限时返回
ERR_FULL,不静默丢弃 - 线程安全: 当前版本不内置锁。单任务场景(MQTT 回调 + 采集任务通过消息队列)无需锁
- 数据不持久化: bench 纯运行时,重启后需重新 put 数据和注册工具