2012-05-27 53 views
2

我以约100帧/秒的速度从相机进入图像流,每张图像大约2 MB。现在只是因为磁盘写入速度,我知道我不能写每一帧,所以我只是试图每秒钟节省大约三分之一的帧。将数据流写入磁盘的最快方法

流是大型字符数组的循环缓冲区。现在我使用fwrite将每个阵列转储到缓冲的临时文件,但它似乎只能以20-30 MB/s的速度写入,而理论上硬盘的速度应该高达80-100 MB/s, s

有什么想法?有没有比fwrite()更快的编写方式或优化它的方法? 更一般地说,将大量数据转储到标准硬盘驱动器的最快方法是什么?

+2

在* nix系统上使用特定于操作系统的调用,比如'write'来获得无缓冲的调用? – dirkgently

+0

只是一个提示,但预先分配文件可能会有所帮助;写几千兆字节的'NUL'字节到一个文件中(并且不要只是'fseek()'并在最后写入,这将是[稀疏](http://en.wikipedia.org/wiki/Sparse_file )),因此文件系统无需在从摄像机接收数据时找到块的位置。 – Ashe

+0

@dirkgently没有缓冲的话,不会使用原语的效率会降低,除非您传递的是恰好是扇区大小倍数的数据块? – SJuan76

回答

0

fwrite被缓冲,这就是你想要的。尽管对于那些大文件/写入来说,它应该没有太大的区别。也许用setbuf调用试验一个更大的流缓冲区。

由于您受物理磁盘I/O速度的限制,只要您尽可能简化系统以便高效地使用每个可用磁盘,就不会有更多的事情可做。在Linux上(其他系统上的其他类似工具)可以告诉你磁盘正在做多少磁盘I/O,因此您可以测试您的更改是否有所帮助。

1

如果您将内存映射文件限制为例如每个1GB,该怎么办?这应该提供足够的速度和缓冲区来处理所有帧,特别是如果您设法执行零拷贝帧分配。

+0

从我读过的内存映射文件最适合多个读取和写入同一个文件。但该文件必须足够小以适应内存正确?我需要写几十到几百千兆字节。 – user1359341

+0

好吧,如果你使用的是POSIX系统,请检查'mmap'限制。据我所知,有限制的最大字节同时映射到内存。 对于使用'CreateFileMapping'的Windows系统,您可以创建无限大小的文件,但是当您使用内存本身时,应该使用'MapViewOfFile'来保留它,并且这仅限于应用程序的空间地址。 注意:这两个系统都偏向与页面大小对齐的大小。 – Forgottn

0

异步非缓冲输出是成功的关键。缓冲IO只会导致双缓冲开销,并且同步IO将使HDD磁头缺少连续扇区。

Boost.Asio为流行平台提供了相对良好的系统特定API封装。

有要记住几件事情:

    在大多数非Windows平台
  • 你将不得不写原始分区去得到系统的bufferization和内螺纹的出路。
  • 始终保持写队列非空,所以SATA控制器可以通过NCQ帮助您。
  • 注意系统特定的要求以缓冲异步非缓冲IO工作的对齐和大小。
  • 文件打开模式对于使系统做你想做的事也很重要。
+0

异步I/O是否适用于此?我已经看过它,但它似乎总是令人难以置信,特别是没有文件的Boost.Asio。 似乎只有在写入之间要进行处理时才会有所帮助,以便在写入时发生。但是,由于所有人都在写缓冲区,这会有帮助吗? – user1359341

+0

@ user1359341 - 好吧,如果你的缓冲区相对较大(数百MB),那么即使在阻止IO的情况下(因为你在任何特定时刻只进行一次写入),你也可能达到HD的最高写入速度。但是,如何让你的系统自动平衡?例如,您希望使丢帧率成为输出流速度的函数。 HDD的速度可能会因HDD的不同而异,具体取决于您写的是什么轨道,或者如果您设置RAID或升级到SSD等,可能会发生显着变化。因此,中型AIO事件驱动架构是正确的选择。 – Krit

相关问题