我有一个具有顺序写入功能的磁盘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);
}
不幸的是,在释放模式下(根据Windows Profiler),我只能获得大约370-500 Mb / s的写入速度。
writeFrameToFile是最慢的操作,在调试模式下需要12-13毫秒。
是否允许并行文件写入,或者ssd无法在并行线程中写入?我可以使用多个SSD吗?
谢谢。
最佳答案
如果您使用的是Linux系统,请考虑将文件映射到内存。
您可以事先知道文件大小,然后指示操作系统使用mmap()
之类的功能来建立显式的内存映射。然后,文件的全部内容将映射到程序的虚拟内存空间,写入文件变得非常简单,就像在两个内存缓冲区之间复制数据一样。
当然,整个文件不必在写入过程中放入内存中。但是,这种方法的强大之处就在于此。通过让操作系统为您映射内存,通常用于直写式缓存和页面预取的相同机制将写入的页面异步转储到磁盘上的实际文件中。这样,您的程序就可以继续编写,并且操作系统本身可以安排实际I / O发生的时间/时间(通常在其他CPU内核上,而不会暂停程序的执行)。此外,操作系统还可以适当选择块大小。
TL; DR:
文件映射为您提供了Linux上强大的异步I / O。
您无需担心缓冲区大小。操作系统会为您发出正确的呼叫。
设置可能更复杂,但是一旦完成,您就可以像写入内存缓冲区一样优雅地写入文件。
有关更多信息,请查看the manual page和this example on Gist。
编辑:从评论,我现在看到您在Windows上。使用CreateFileMappingA()
可以完成相同的操作。可以在this article中找到更多信息。
关于c++ - 如何提高多相机设置的写入速度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52592073/