在不减慢线程速度的情况下保存大量数据



我需要保存视频系统的痕迹,以便以后在Windows机器上进行检查回放。

帧生成是在线程中完成的,我想在处理功能结束时保存帧,例如

void generate_video_frame() {
....
save_frame(frame);
}

为了避免减慢生成线程的速度save_frame必须尽快完成此操作。最终目标是获得磁盘保存的视频跟踪。

每一帧都可能非常大(甚至 20-30 MB(,所以我不能只将所有内容存储在 RAM 中,因为我最终会完全填满它。

我想到了两个解决方案:

  • 填充帧队列并使用另一个线程清空它并将其刷新到磁盘(这样主线程就不会受到影响(。如果刷新到磁盘的线程较慢(如我所料(,这最终也可能填满 RAM

  • 使用映射文件并尽快写入每一帧

有没有更好的方法?如果没有,我应该注意哪些缺点/注意事项?

这取决于。你们的框架的来源是什么?它们是否来自实时源,即相机,然后以某种方式进行处理?或者它们只是从任何类型的数据生成(并且没有来自数据源的实时压力(。

你的问题以某种方式暗示了后者。如果是这种情况,我建议确实在不同的线程中运行创建并写入磁盘。实际上,可能还有更多,您可能不仅有两个任务,而且有三个任务:

  1. 图像数据的生成
  2. 视频数据编码
  3. 将视频数据写入磁盘

第一个似乎不是您的瓶颈,所以我建议运行它并填满队列,直到您运行超过队列的某个限制(以避免耗尽 RAM(,然后等待。

第二种是编码,以牺牲处理时间为代价压缩数据。一旦图像存在,就可以独立于生成来完成。这里有很多选择(从无损编解码器到具有不同质量的有损编解码器(,但通常值得这样做。在此之后,您只能将压缩数据存储在 RAM 中,从而减少 RAM 的使用量。另一方面,这当然会消耗一些处理能力,并且(假设它已经是多线程的(可能会减慢您的数据创建速度。因此,在这里,您可以平衡数据大小与生成速度,以实现最佳平衡。

最后,写入磁盘。如果您写入未压缩的数据,则很多。如果它被压缩,没有那么多。由于写入磁盘通常有点慢,因此写入较少的数据当然会有所帮助。此外,写入较大的数据块比写入少量数据更有效。因此,收集几帧并一次编写它们可能会节省您的时间。

这里有很多螺丝钉可以优化。您的目标似乎是尽快拥有整个系统。问题通常是何时投入工作来做到这一点。如果你正在开发的任何东西都在工作,而且它只是关于性能,你可能会去做。如果你只是关心这个,但你最后想做的事情还没有完成,我总是建议先让它运行,然后再让它快速运行。

相关内容

最新更新