Cat*_*tus 5 c++ buffering circular-buffer data-acquisition
我有一个产生数据流的仪器;我的代码通过回调访问这些数据onDataAcquisitionEvent(const InstrumentOutput &data)。数据处理算法可能比数据到达的速度慢得多,所以我不能希望处理每一条数据(我没有必要),但希望处理尽可能多的数据。感谢该仪器作为环境传感器,其数据采集速率是我无法控制的。InstrumentOutput例如,可以是包含三个在不同位置同时进行的压力测量的类。
我还需要保留一些简短的数据历史记录。例如,假设我可以合理地希望每 200 毫秒左右处理一个数据样本。大多数情况下,我很乐意只处理最后一个样本,但有时我需要查看在最新样本之前到达的几秒钟的数据,这取决于最后一个样本中是否存在异常读数。
另一个要求是尽快退出onDataAcquisitionEvent()回调,以避免传感器中的数据丢失。
数据采集库(第三方)在单独的线程上采集仪器数据。
我想到了以下设计;具有单个生产者/单个消费者队列,并在 onDataAcquisitionEvent() 回调中将数据令牌推送到同步队列中。
在接收端,有一个循环从队列中弹出数据。由于数据到达率很高,循环几乎不会休眠。在每次迭代中,会发生以下情况:
问题:
编辑:我想到的一个问题是,当循环缓冲区的大小不足以容纳所需的历史记录时;目前我只是重新分配循环缓冲区,将其大小加倍。我希望我只需要这样做一两次。
我在数据获取方面有一些经验,我可以告诉你很多开发人员都遇到过早的功能蔓延问题。因为将仪器中的数据捕获到日志中听起来很容易,所以人们倾向于在验证日志记录实际上是否可靠之前向系统添加不必要的组件。这是一个大错误。
onDataAcquisitionEvent()另一个要求是尽快退出回调,以避免传感器中的数据丢失。
这是产品该部分在所有现场条件下 110% 工作之前的唯一要求。
大多数时候,我很乐意只处理最后一个样本,但有时我需要查看在最新样本之前到达的几秒钟的数据,具体取决于最后一个样本中是否存在异常读数。
“大多数时候”并不重要。针对最坏情况编写代码,因为onDataAcquisitionEvent()不能花时间考虑意外情况。
听起来你好像陷入了一个陷阱,将其设计为使用可能可用的最佳数据,并保留如果数据不可用或向监视器提供最佳数据最终成本太高时可能发生的情况。
从源头减少数据。指定异常案例处理需要多少样本,并尝试以恒定的样本率提供该数量的样本,再加上大约 20% 的裕度。
当然不应该有永不休眠的循环。循环缓冲区很好,但只需用您需要的最小值填充它,并仅根据需要频繁地分析它。
系统的质量是由其稳定性和确定性决定的,而不是试图多走一步并提供尽可能多的东西。