0

我有一个程序,它从不同的相机获取原始数据流并将其写入磁盘。该程序运行这些类型的记录约 2 分钟,然后使用另一个程序来处理这些帧。

每个原始帧为 2MB,帧速率为 30fps(即数据速率约为 60MB/s),我正在写入可以轻松处理持续 > 150MB/s 的 SSD(通过从另一个磁盘复制 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

IE。~5ms 运行整个函数,~1ms 打开文件,~2ms 调用 write,~2ms 关闭文件。

然而,偶尔(平均每 50 帧中约有 1 帧,但有时发生此问题之间可能有数千帧),我得到的帧需要超过 4000 毫秒:

TotalT,4032,    FOpenT,4023,    FWriteT,6,    FCloseT,3

TotalT,1533,    FOpenT,1,       FWriteT,2,    FCloseT,1530

所有的框架都是相同的大小,它永远不会fwrite花费额外的时间,总是fopenfclose

没有其他进程正在读取/写入此 SSD(通过 Process Monitor 确认)。

有谁知道什么可能导致这个问题和/或任何避免/减轻这个问题的方法?

4

2 回答 2

1

我将支持 XJ,您可能将太多文件写入单个目录。一种解决方案可能是为每批帧创建一个新目录。还可以考虑在创建文件后直接调用SetEndOfFile,因为这将有助于 Windows 在单个操作中分配足够的空间。

FAT 不是一个真正的解决方案,因为它在大型目录上做得更糟。

于 2014-01-17T09:30:59.590 回答
1

准备空文件(用零填充的 2 MB 文件)以便空间已经“准备好”,然后覆盖这些文件。或者创建一个包含多个帧的批次的文件,这样您就可以减少文件的数量。

有用于压缩和解压缩和播放视频的库:

libTheora 可能很有用,因为已经压缩了帧(你需要将视频输出到单个文件中)并且做得非常快(顺便说一下有损压缩)。

于 2014-01-17T09:41:08.897 回答