我有一个程序可以从不同的摄像头获取原始数据流并将其写入磁盘。该程序运行这些类型的录音约2分钟,然后另一个程序用于处理帧。
每个原始帧为2MB,帧速率为30fps(即数据速率约为60MB / s),我正在写入一个可以轻松处理持续的>的SSD。 150MB / s(通过从另一个磁盘复制4000个2MB文件进行测试,耗时38秒,Process Explorer显示持续的IO活动)。
我的问题是,偶尔会调用fopen()
,fwrite()
和fclose()
停顿最多5秒,这意味着300MB的帧会在内存中作为后台日志累积,之后其中一些延迟我达到了32位进程的4GB限制。 (当延迟发生时,Process Explorer显示IO活动的间隙)
有一个线程运行一个循环,为每个被添加到队列的新帧调用此函数:
writeFrame(char* data, size_t dataSize, char* filepath)
{
// Time block 2
FILE* pFile = NULL;
fopen(&pFile, filepath, "wb");
// End Time block 2
// Time block 3
fwrite(data,1,dataSize,pFile);
// End Time block 3
// Time block 4
fclose(pFile);
// End Time block 4
}
(在实际代码中也有错误检查,但这对此问题没有影响) 我正在记录每个块所花费的时间以及运行该函数所需的总时间,并且我得到的结果大部分时间都是这样的:(以毫秒为单位)
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
TotalT,4, FOpenT,1, FWriteT,1, FCloseT,2
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
即。 〜5ms运行整个功能,~1ms打开文件,~2ms调用写入~2ms关闭文件。
然而偶尔(平均每50帧中大约有1帧,但有时在这个问题发生之间可能有数千帧),我得到的帧数超过4000毫秒:
TotalT,4032, FOpenT,4023, FWriteT,6, FCloseT,3
和
TotalT,1533, FOpenT,1, FWriteT,2, FCloseT,1530
所有框架都是相同的尺寸,永远不会fwrite
占用额外的时间,始终为fopen
或fclose
没有其他进程正在读取/写入此SSD(使用Process Monitor确认)。
是否有人知道可能导致此问题的原因和/或避免/缓解此问题的方法?
答案 0 :(得分:1)
我要支持X.J.,你可能在一个目录上写了太多文件。
解决方案可以是为每批帧创建一个新目录。还可以考虑在创建文件后直接调用SetEndOfFile
,因为这将有助于Windows在单个操作中分配足够的空间。
FAT并不是一个真正的解决方案,因为它在大型目录上的表现更差。
答案 1 :(得分:1)
准备空文件(填充零的2 MB文件)这样空间已经“准备好”,然后只是覆盖这些文件。或者创建一个包含多个帧的文件,这样可以减少文件数量。
有用于压缩,解压缩和播放视频的库:
libTheora可能很有用,因为已经压缩帧(你需要在单个文件中输出视频)并且这样做非常快(顺便说一下有损压缩)。