5

我正在编写一个小应用程序,它以恒定速率在 SD 卡上写入 jpeg 图像。我选择了 EXT3 文件系统,但使用 EXT2 文件系统观察到了相同的行为。

我的写作循环如下所示:

get_image()
fwrite()
fsync()

或者像这样:

get_image()
fopen() 
fwrite()
fsync()
fclose()

我还显示了一些计时统计信息,我可以看到我的程序有时被阻塞了几秒钟。平均速率还是不错的,因为如果我将传入的图像保持在一个 fifo 中,那么我会在这样的停顿后的短时间内写入很多图像。你知道这是操作系统的问题还是与SD卡本身有关?我怎样才能更接近实时?我不需要强大的实时性,但是停滞几秒钟是不可接受的。

一些精度:是的,有必要在每个文件之后进行 fsync,因为我希望图像在磁盘上,而不是在某些用户或内核缓冲区中。没有 fsyncing,我的直通输出要好得多,但仍然是不可接受的停顿。我认为这不是缓冲区问题,因为第一次停顿发生在写入 50 MB 之后。根据手册页, fsync 正是为了确保没有缓冲数据。

关于平均写入速率的精度:我正在以我正在使用的卡可持续的速率写入。如果我在等待 fsync 完成时堆积传入的图像,那么在这个停顿之后,写入传输速率会增加,我会很快回到平均速率。平均传输速率约为 1.4 MBytes / s。

systeme 是运行 ubuntu 8.04 和 stock kee (2.6.24.19) 的现代笔记本电脑

4

7 回答 7

4

尝试打开文件O_DIRECT并在应用程序级别进行缓存。

当我们在 STB Box 中实现 PVR(个人视频录制)功能时,我们遇到了类似的问题。这个O_DIRECT技巧最终满足了我们的需求。(*)

没有O_DIRECT. 的数据write()将首先缓存在内核缓冲区中,然后在您调用fsync或内核缓存缓冲区已满时刷新到媒体。(**)。

使用O_DIRECT.Th 内核将直接对作为参数传递给系统调用的用户空间缓冲区指向的物理内存进行 DMA write。因此在用户空间内存和内核缓存之间的副本中不会花费 CPU 和内存带宽,并且不会在内核中花费 CPU 时间来管理缓存(如缓存查找、每页锁定等)。 (从这里复制)

不确定它是否也能解决您的问题,但您可能想尝试一下。

*尽管 Linus批评O_DIRECT,但它确实解决了我们的问题。

** 假设您没有使用O_DSYNCor打开文件O_SYNC

于 2010-01-20T02:09:38.760 回答
3

是否有必要fsync()在每个文件之后?让操作系统决定何时将所有排队的图像写入 SD 卡可能会有更好的运气(分摊在许多图像上操作 SD 卡文件系统的启动成本,而不是为每个图像产生它)。

您能否提供有关您的平台的更多详细信息?缓慢的 I/O 时间可能与系统上的其他进程、缓慢的 I/O 控制器等有关。

您也可以考虑使用更适合闪存工作方式的文件系统。FAT32 比 FAT32 更常见extN,但专门为 SD 构建的文件系统也可能需要。 JFFS就是一个很好的例子。使用专为闪存设计的文件系统(而不是旋转磁介质),您可能会获得更好的性能,并且还可以获得更好的磨损均衡(以及设备寿命/可靠性)属性。

于 2008-10-10T16:18:14.623 回答
2

AFAIK 一些闪存盘的写入性能非常差(尤其是廉价品牌)。因此,如果您测量应用程序的写入速度(包括 fsync 所需的时间),您会得到什么?它可能很容易达到每秒几兆字节的数量级 - 只是因为硬件没有做得更好。

此外,如果您写入许多小块而不是一个大块,显然写入可能会慢得多(闪存盘每秒可能只能完成大约 10 次写入,在糟糕的情况下)。这可能是内核缓冲区可以缓解的问题,因此频繁使用 fsync 可能会减慢写入速度……

顺便提一句。你测量过 FAT32 的写入性能吗?我猜它差不多,但如果不是,也许还有一些优化可用?

于 2008-10-13T20:34:05.603 回答
1

我在这方面不是很了解,但是您描述的症状听起来很像填充缓冲区。您可能正在文件写入器或与 SD 卡本身通信的 I/O 设备中填充缓冲区。然后,您必须等到它实际将数据写入卡(从而清空缓冲区)才能写入更多数据。SD 卡的写入速度不是特别快。如果你能找到一种方法来检查在这些暂停期间数据是否真的被写入卡,那将验证我的理论。一些读卡器有一个 LED 灯,当数据被访问时会闪烁——这可能是一个很好的指标。

只是一种预感……加点盐吧:)

于 2008-10-10T16:17:23.533 回答
1

可能这会有所帮助 -基准文件系统

...我很惊讶 ext3 的整体速度有多慢,因为许多发行版都使用这个文件系统作为他们的默认文件系统...

“ext3 fsync 批处理”

...此补丁测量将事务提交到磁盘所需的时间,并根据底层磁盘的速度休眠。

于 2009-01-12T02:16:55.643 回答
0

对于阅读本文并使用 2.6.28 以上内核的任何人,建议使用 ext4 而不是 ext3,这是一个可以调整以获得更好性能的文件系统。在不记录数据的 data=writeback 模式下获得最佳性能。从https://www.kernel.org/doc/Documentation/filesystems/ext4.txt阅读数据模式部分。

如果您已经创建了一个分区,例如/dev/sdb1,那么这些步骤可用于使用 ext4 对其进行格式化而无需记录日志:

mkfs.ext4 /dev/sdb1 -L jp  # Creates the ext4 filesystem
tune2fs -o journal_data_writeback /dev/sdb1 # Set to writeback mode
tune2fs -O ^has_journal /dev/sdb1 # Disable journaling
sudo e2fsck -f /dev/sdb1 # Filesystem check is required

然后,您可以使用相应的标志挂载此分区(或设置一个条目/etc/fstab,如果您知道自己在做什么):

mount -t ext4 -O noatime,nodirame,data=writeback /dev/mmcblk0p1 /mnt/sd

从 ext3 迁移到优化的 ext4 文件系统应该是一个巨大的区别。而且,当然,如果您的 SD 卡更快,那应该会有所帮助(即 10 级)。

另请参阅https://developer.ridgerun.com/wiki/index.php/High_performance_SD_card_tuning_using_the_EXT4_file_system

于 2014-02-13T22:26:44.373 回答
-1

也可以考虑 SD 卡,是 NOR 还是 NAND?此页面显示了 SD 卡之间的数量级(2M/s 与 20M/s)。
http://www.robgalbraith.com/bins/camera_multi_page.asp?cid=6007-9597
我认为 ZFS 针对闪存进行了优化。

于 2009-02-12T20:30:41.330 回答