c - 优化数据流到C盘(也是闪存)

标签 c linux

我有一个在 Linux 上运行的 C 程序,它从 USB 设备获取数据(传感器数据),进行一些处理并将结果流式传输到磁盘。目前我使用 fputs() 保存到一个文本文件,一行看起来像这样:

timestamp    value1    value2    ...    valueN

采样率高达 250Hz。

该程序应在 RPi 或类似板上运行,并可能将数据写入闪存(SD 卡)。

我有以下问题:

  1. 我应该优化数据流还是让操作系统来完成这项工作?更具体地说,我是否应该尽量减少实际将数据写入磁盘的频率(也考虑到使用闪存)?
  2. 我已经阅读了有关 setbuf()setvbuf() 的内容,据我所知,它们应该有效地延迟写入,直到“ block ”被填满。这些是否合适,或者是否有比实现我自己的缓冲区更好的方法?
  3. 考虑到上述情况,哪个输出函数最适合数据流 (fputs()/fprintf()/write() )?
  4. 在写入 SD 卡时,我是否应该尝试增加随机性(例如使用所有扇区)?如果是,实现此目标的最佳方法是什么?

这里还有一些想法:

  • 我可以考虑使用二进制格式来减小大小,但我更愿意保留文本格式以简化以后的数据处理。
  • 在最终设计中使用硬盘驱动器也是一个选项,特别是如果要长时间保持高采集率。
  • 数据速率相对较低 我不认为硬盘驱动器或 SD 卡存在带宽问题。 future 速率可能会更高(kHz 或更高)。

感谢您的回答。

编辑 20130128 到目前为止,感谢您提供的所有答案,它们给了我一些很好的见解。我总结一下:

  • 一般来说,我不应该有带宽问题,但是为了避免不必要的大日志文件,我可能会考虑二进制格式。是的,日志应该是人类可读的,如果不是,我会做一个导出功能或类似的。是的,unwind 的假设是正确的,每行大约 10 或 15 个数据值。
  • 提到的每个单元格的读/写周期应该足够一段时间,至少在测试阶段,考虑到我们并不总是写入和删除相同的单元格。我将在 setvbuf() 中调整缓冲区大小,并将缓冲模式设置为全缓冲,看看我是否可以优化它,同时保持合理的保存间隔(几秒或更长时间也取决于采样率).
  • 在最终设计中,我可能会使用硬盘驱动器来避免这里提到的大部分问题,或者使用可以轻松更换的第二张 SD 卡(也可能有助于快速检索数据)。我将使用此处建议的格式之一(FAT 或 JFFS2/F2FS)对其进行格式化。
  • 根据 zmo 的建议,我将尝试使系统尽可能只读(至少是系统分区),我已经在考虑这一点。
  • 如果我对 RPi 不满意,那么 zmo 也提到了 Beaglebone,这是我的下一个选择(我读到它的 USB 总线并不总是稳定的,USB 显然对我的应用程序非常重要)。
  • 我已经实现了一个 UDP 端口来通过网络发送数据,但我仍然希望至少保留该数据的本地副本,并且可能只发送一部分或已经处理过的数据,以及“控制数据”。

最佳答案

Should I be optimizing the data stream or let the OS do the job? More specifically, should I be trying to minimize how often data is actually written to disk (also given the use of a flash memory)?

好吧,您通常可以假设操作系统在缓冲和处理硬盘驱动器输出方面做得非常出色……只要您不进行无缓冲写入。

不过,根据我的经验,您不应该将日志写入 SD 卡,因为它肯定比您想象的更快地杀死 SD 卡。在我的第一个项目中,我在 beaglebones 上安装了 linux,6 个月到 12 个月后,我所有的 SD 卡都必须更换......

从那时起,我学会了在 SD 卡上运行只读系统并通过网络发送任何类型的定期更新,诀窍是为 /tmp/var.

在您的情况下,使用硬盘驱动器是一个简单的解决方案(可以顺利运行),但您也可以使用辅助 SD 卡来写入日志。然后你就可以使用一个“愚蠢的”文件系统,比如 FAT 文件系统,你可以在其中对齐写入数据,因为你的数据将是唯一要写入 SD 的东西。导致 SDCard 卡死的原因是经常发生在临时文件和驱动器碎片整理中的大量小读/写。

I have read about setbuf() and setvbuf(), as I understand they should effectively delay writing until a "block" is filled. Are these appropriate or is there a better way other than perhaps implementing my own buffer?

好吧,只要保持全缓冲,这将有助于写入在文件系统上对齐的数据。

Which output function is best suited for data streaming with the above in mind (fputs() / fprintf() / write())?

对于您的问题,它们的行为应该都相似。

Should I be trying to increase randomness (as to use all sectors) when writing to a SD card? If yes what's the best way to achieve this?

sdcard 的固件应该会为您解决这个问题。唯一的办法是使用更简单的文件系统,如 FAT(或 JFFS2/F2FS,如 ivan-voras suggets),因为 ext2/ext3/ext4 文件系统会自动进行碎片整理,这基本上是在 inode 周围移动以保留所有内容对齐。虽然我不确定它是否会禁用 SD 卡和 SSD 的这种行为。

关于c - 优化数据流到C盘(也是闪存),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21379659/

相关文章:

linux - 你能在 Linux 上运行 Xcode 吗?

python - 监听 dbus 信号以在 debian linux 上挂载 mtp 设备

检查矩阵

c - 在某些 C 文件中无法看到全局变量,值似乎已重置

c - 语句表达式中的 'redefining' 变量安全吗?

linux - netstat -p 标志不起作用

linux - 找出进程在 Linux 中休眠了多长时间?

linux - 如何使用内核模块监控进程创建和统计

c++ - 进程 ID 和进程名称

c - zlib 是否允许从文件中间解压