我正在从事一个嵌入式Linux项目,该项目将ARM9连接到硬件视频编码器芯片,并将视频写到SD卡或USB记忆棒中。该软件体系结构包括将数据读入缓冲池的内核驱动程序,以及将数据写入已安装的可移动设备上的文件的用户态应用程序。
我发现在一定的数据速率(大约750kbyte / sec)以上时,我开始看到userland视频编写应用程序停顿了大约半秒钟,大约每5秒钟。这足以使内核驱动程序用尽缓冲区- 即使我可以增加缓冲区的数量,也必须将视频数据与实时进行的其他事情同步(最好在40ms之内)。在这5秒的“滞后尖峰”之间,写入在40ms内完成得很好(就应用程序而言- 我感谢它们被操作系统缓冲)
我认为这种延迟高峰与Linux将数据刷新到磁盘的方式有关- 我注意到pdflush设计为每5秒唤醒一次,我的理解是,这就是编写的内容。一旦停滞结束,userland应用程序便能够快速服务并编写缓冲区的积压(未溢出)。
我认为我正在写入的设备具有合理的最终吞吐量:从内存fs复制15MB文件并等待同步完成(并且USB记忆棒的光停止闪烁)使我的写入速度约为2.7MBytes / sec。
我正在寻找两种线索:
如何阻止突发写入停止我的应用程序-可能处理优先级,实时补丁或调整文件系统代码以连续写入而不是突发写入?
如何使我的应用程序从写入积压和卡/棒的吞吐量方面了解文件系统的状况?我可以即时更改硬件编解码器中的视频比特率,这比丢弃帧或对最大允许比特率施加人为上限要好得多。
更多信息:这是一个200MHz的ARM9,当前运行基于Montavista 2.6.10的内核。
更新:
我希望这是有道理的。关于stackoverflow的第一个嵌入式Linux问题?:)
据记录,除了最极端的情况外,似乎有两个主要方面消除了这个问题。该系统仍在开发中,尚未经过严格的折磨测试,但运行良好(触摸木头)。
最大的胜利来自使userland writer应用程序成为多线程。有时会阻塞对write()的调用:其他进程和线程仍在运行。只要我有一个线程为设备驱动程序提供服务并更新帧数和其他数据以与正在运行的其他应用程序同步,就可以在几秒钟后对数据进行缓冲和写出,而不会中断任何截止日期。我首先尝试了一个简单的乒乓双缓冲,但这还不够。小缓冲区将不堪重负,大缓冲区将导致较大的暂停,而文件系统消化了写入操作。在线程之间排队的10个1MB缓冲区池现在运行良好。
另一方面是关注物理介质的最终写入吞吐量。为此,我一直关注stat脏:/ proc / meminfo报告。如果“脏”,我有一些粗糙的现成代码可以限制编码器:爬到某个阈值之上,似乎可以正常工作。以后需要更多测试和调整。幸运的是,我有很多RAM(128M)可以玩,给了我几秒钟的时间来查看积压的积压和平稳地减少油压。
如果我发现需要采取其他措施来解决此问题,我会尽量记住弹出并更新此答案。多亏了其他回答者。