保存大量数据而不会减慢线程

时间:2018-05-24 09:42:49

标签: c++ windows multithreading performance serialization

我需要保存一段视频系统,以便以后在Windows机器上进行检查重播。

帧生成是在一个线程中完成的,我想在处理函数结束时保存帧,例如

void generate_video_frame() {

    ....

    save_frame(frame);
}

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

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

我想到了两个解决方案:

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

  • 使用mapped file并尽快写下每一帧

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

1 个答案:

答案 0 :(得分:0)

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

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

  1. 生成图像数据
  2. 视频数据编码
  3. 将视频数据写入磁盘
  4. 第一个似乎不是你的瓶颈,所以我建议运行它并填满队列,直到你超过队列的某个限制(以避免耗尽RAM),然后等待。

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

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

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