背景
我目前正在开发一个小应用程序,它可以从Microsoft Kinect设备上抓取RGB和深度图数据流,并将它们保存在磁盘上以供将来分析。当我运行该程序时,它将在磁盘上将每个帧作为单独的图像输出。
Kinect的帧率是30fps,但有两个来源,所以(大约) 60fps。如果我天真地尝试在每个帧到达时保存它,我将得到丢弃的帧,正如捆绑的freenect/record.c应用程序所演示的那样。
我重写了应用程序,使用一个线程从设备获取帧,并将它们推送到双端列表(std::deque)的后面。然后有两个线程,每个线程从双端列表的前面弹出帧,并将帧保存到磁盘。当记录被关闭时,列表中可能还有大量的帧需要记录,因此在退出之前,我们让两个保存线程完成它们的工作,直到完成。
现在真正的问题是
虽然丢帧的问题已经解决,但写入文件系统的速度仍然相当慢。有没有什么好的方法来加速磁盘上的文件创建?目前,函数dump_frame如下所示:
static void
dump_frame(struct frame* frame)
{
FILE* fp;
char filename[512]; /* plenty of space! */
sprintf(filename, "d-%f-%u.pgm", get_time, frame->timestamp);
fp = fopen(filename, "w");
fprintf(fp, "P5 %d %d 65535\n", frame->width, frame->height);
fwrite(frame->data, frame->size, 1, fp);
fclose(fp);
}我运行的是Fedora14 x64,所以这个解决方案只需要把Linux作为操作系统。
发布于 2012-01-12 21:33:23
您需要衡量在您的特定情况下什么需要时间。是创建多个文件还是将图像数据实际写入磁盘?
当我在我的本地系统上使用OSX和英特尔固态硬盘X25M 2G进行测试时,我注意到写入多个1MB文件与写入1个多MB文件时存在巨大的写入差异。这可能是由于文件系统的内务管理,并将根据您拥有的文件系统而有所不同。
为了避免内部事务,您可以将所有图像放到同一个文件中,然后再拆分它。然而,您要保存的数据需要大约60MB的持续速度,这是相当高的。
如果您有大量内存,另一种方法是先创建一个ram磁盘并将图像存储在那里,然后再将它们移到持久文件系统中。使用6 6GB的内存磁盘,您可以存储大约100秒的视频。
发布于 2012-01-12 20:18:11
一种可能的改进是使用setvbuf显式地将fp的缓冲设置为full
const size_t BUFFER_SIZE = 1024 * 16;
fp = fopen(filename, "w");
setvbuf(fp, 0, _IOFBF, BUFFER_SIZE)); /* Must be immediately after the open. */
fprintf(fp, "P5 %d %d 65535\n", frame->width, frame->height);
fwrite(frame->data, frame->size, 1, fp);
fclose(fp);您可以使用不同的缓冲区大小进行性能分析,以确定哪个缓冲区提供最佳性能。
https://stackoverflow.com/questions/8834836
复制相似问题