Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在不降低线程速度的情况下保存大量数据_C++_Windows_Multithreading_Performance_Serialization - Fatal编程技术网

C++ 在不降低线程速度的情况下保存大量数据

C++ 在不降低线程速度的情况下保存大量数据,c++,windows,multithreading,performance,serialization,C++,Windows,Multithreading,Performance,Serialization,我需要保存一个视频系统的跟踪,以便以后在Windows机器上进行检查回放 帧生成是在线程中完成的,我想在处理函数的末尾保存帧,例如 void generate_video_frame() { .... save_frame(frame); } 为避免降低生成线程的速度,save_frame必须尽快完成此操作。最终目标是将视频的轨迹保存到磁盘上 每个帧可以相当大(甚至20-30MB),所以我不能将所有内容都存储在RAM中,因为我最终会将其完全填满 我想到了两种解决方案: 填

我需要保存一个视频系统的跟踪,以便以后在Windows机器上进行检查回放

帧生成是在线程中完成的,我想在处理函数的末尾保存帧,例如

void generate_video_frame() {

    ....

    save_frame(frame);
}
为避免降低生成线程的速度,
save_frame
必须尽快完成此操作。最终目标是将视频的轨迹保存到磁盘上

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

我想到了两种解决方案:

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

  • 使用a,尽可能快地写下每一帧


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

这取决于具体情况。你的镜框的来源是什么?它们是否来自实时来源,即摄像头,然后以某种方式进行处理?或者它们仅仅是由任何类型的数据生成的(并且没有来自数据源的实时压力)

你的问题似乎暗示了后者。如果是这种情况,我建议确实在不同的线程中运行创建和写入磁盘。事实上,可能还有更多,你可能不仅有两项任务,还有三项:

  • 图像数据的生成
  • 视频数据的编码
  • 将视频数据写入磁盘
  • 第一个问题似乎不是您的瓶颈,因此我建议您运行它并填充一个队列,直到您运行到队列的某个限制之上(以避免耗尽RAM),然后再等待

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

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


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

    写入文件asynchronous@RbMm写入文件异步一个问题是错误处理——当有50个等待异步写入的IO请求排队时,如何干净地处理IO错误?另一种方法是管理数据缓冲区,在异步写入完成之前,这些缓冲区可能必须保持不变。正如OP所建议的,将帧对象放入写入线程队列可能会容易得多。每个帧都可能相当大(甚至20-30MB),因此我不能将所有内容都存储在RAM中,因为我最终会将其完全填满。限制队列大小-一旦队列达到某个大小,让生产者线程阻塞,直到尝试添加到队列时队列大小下降。是的,它会减慢帧生成速度,但最终帧生成速度受限于您写入磁盘的速度。@AndrewHenle-当然可以。有多少未决io请求在此处不起作用all@RbMm存在多少未决io请求根本不起作用,当然未决io请求的数量起作用。在异步写入完成之前,保存要写入的数据的内存缓冲区不能再用于其他目的。缓冲区需要保留和跟踪,OP已经声明内存使用是一个考虑因素。