【问题标题】:How do I increase writing speed for multi camera setup?如何提高多相机设置的写入速度?
【发布时间】:2019-03-06 14:53:00
【问题描述】:

我有一个顺序写入能力为 1572 Mb/秒的磁盘

我有 4 个 60 fps 的摄像机。每帧没有编码,是 3.7 Mb(比方说 4 Mb)的图像。 我需要的写入速度是 4*4*60 = 960 Mb/s。

PointGrey 提供示例代码:

for (unsigned int uiCamera = 0; uiCamera < numCameras; uiCamera++)
    {
        error = retrieveImage(ppCameras[uiCamera], &image);
        // error = ppCameras[uiCamera]->RetrieveBuffer(&image);
        if (error != PGRERROR_OK)
        {
            PrintError(error);
            cout << "Press Enter to exit." << endl;
            cin.ignore();
            return -1;
        }

        // Get the size of the buffer associated with the image, in bytes.
        // Returns the size of the buffer in bytes.
        iImageSize = image.GetDataSize();

        // Write to the file
        ardwBytesWritten[uiCamera] = writeFrameToFile(m_ALLCAMS, image);


};

在哪里:

size_t writeFrameToFile(FILE* f, Image image)
{
    return fwrite(image.GetData(),
        1,
        image.GetCols() * image.GetRows(),
        f);
}

不幸的是,我在发布模式下只能获得大约 370 - 500 Mb/s 的写入速度(根据 windows profiler)。

writeFrameToFile 是最慢的操作,在调试模式下需要 12-13 毫秒。

并行文件写入是否有意义,或者 ssd 不能在并行线程中写入?我应该使用多个 SSD 吗? 谢谢你。

【问题讨论】:

  • 由于您不是直接访问 SSD 而是通过操作系统,因此您不能依赖额定的顺序写入速度。您的操作系统会将每个文件块写入 SSD 上它感到有这样做的冲动的任何块。它可能是顺序的,也可能不是顺序的,并且同时写入多个文件,写入将无处不在。
  • 你能把每个相机都写到它自己的文件里吗?
  • 你的操作系统是什么?
  • 拍摄多长时间,用例是什么?如果它必须长时间连续,您可以考虑通过网络将文件发送到专用机器,其唯一的工作就是将它们写入磁盘。如果您的数据是突发的,您也许可以写入其中的一部分并将其余部分保存在 RAM 中。
  • @SamVarshavchik,Os 是 windows,但如果需要,我可以切换到 linux。如何通过跳过 OS SSD 管理直接录制?

标签: c++ file storage fwrite hard-drive


【解决方案1】:

如果您使用的是 Linux 系统,请考虑将文件映射到内存中

事先知道文件大小,您可以指示操作系统使用mmap() 等函数设置显式内存映射。然后将文件的全部内容映射到程序的虚拟内存空间,写入文件就像在两个内存缓冲区之间复制数据一样简单。

当然,整个文件在写入过程中不需要放入内存中。但这就是这种方法的力量所在。通过让操作系统为您映射内存,通常用于直写缓存和页面预取的相同机制将写入的页面异步转储到磁盘上的实际文件。这样,您的程序可以继续写入,并且操作系统本身会安排实际 I/O 发生的位置/时间(通常在其他 CPU 内核上,而不会暂停程序的执行)。此外,OS也适当地选择块尺寸。

TL;DR:

  • 文件映射在 Linux 上为您提供强大的异步 I/O。
  • 您无需担心缓冲区大小。操作系统会为您做出正确的调用。
  • 设置可能更复杂,但一旦完成,您就可以像写入内存缓冲区一样优雅地写入文件。

如需了解更多信息,请查看the manual pagethis example on Gist

编辑: 从 cmets 中,我现在看到您在 Windows 上。使用CreateFileMappingA() 也可以进行同样的操作。更多信息可以在this article找到。

【讨论】:

    【解决方案2】:

    如果没有其他办法,您最后的办法是通过直接写入磁盘本身来绕过操作系统和文件系统。

    在 Linux 上,您可以通过写入适当的设备来做到这一点,可能在 /dev/disk/by-id/... 的某个地方,在 Windows 上,我什至不知道从哪里开始,但我相当确定这是可能的。

    请注意,这会破坏磁盘上已有的任何内容,因此您只需要一个用于此目的的磁盘,如果您不小心写入了错误的设备,您可能会破坏整个操作系统安装。

    所以这是相当先进和冒险的东西,除了说它可能值得研究之外,我对它的了解还不够多,无法真正提供帮助。

    【讨论】:

      猜你喜欢
      • 2011-10-20
      • 2012-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多