我有一个具有顺序写入功能的磁盘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吗? 谢谢。
答案 0 :(得分:1)
如果您使用的是Linux系统,请考虑将文件映射到内存中。
预先知道文件大小,您可以指示操作系统使用mmap()
之类的功能来建立显式的内存映射。然后,文件的全部内容都将映射到程序的虚拟内存空间,并且写入文件就像在两个内存缓冲区之间复制数据一样简单。
当然,在写入过程中,整个文件不必容纳在内存中。但是,这种方法的强大之处就在于此。通过让操作系统为您映射内存,通常用于直写式缓存和页面预取的相同机制将写入的页面异步转储到磁盘上的实际文件中。这样,您的程序就可以继续编写,并且操作系统本身可以安排实际I / O发生的时间/地点(通常在其他CPU内核上,而不会暂停程序的执行)。此外,操作系统还可以适当选择块大小。
TL; DR:
有关更多信息,请查看the manual page和this example on Gist。
编辑:从评论中,我现在看到您正在使用Windows。使用CreateFileMappingA()
也可以完成相同的操作。可以在this article中找到更多信息。
答案 1 :(得分:0)
如果没有其他效果,那么您最后的选择就是直接写入磁盘本身,从而绕过操作系统和文件系统。
在Linux上,您可以通过写入适当的设备(可能在/ dev / disk / by-id / ...中)来实现此目的,在Windows上,我什至不知道从哪里开始,但我很确定有可能。
请注意,这将浪费磁盘上已有的所有内容,因此您仅需要一块磁盘即可,如果不小心将其写入错误的设备,则可能会浪费整个操作系统的安装。
因此,这是相当高级且冒险的内容,除了说可能值得研究之外,我对它的了解还不够多。