SD卡写性能

时间:2008-10-10 15:51:10

标签: linux real-time ext3 sd-card fsync

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

我的写作循环如下:

get_image()
fwrite()
fsync()

或者像这样:

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

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

一些精确度: 是的,每个文件后都需要fsync,因为我希望图像在磁盘上,而不是在某些用户或内核缓冲区中。没有fsyncing,我有更好的吞吐量, 但仍然是不可接受的失速。我不认为这是一个缓冲区问题,因为第一次失速发生在写入50 MB之后。根据手册页,fsync正是为了确保没有数据缓冲。

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

系统是现代笔记本电脑运行ubuntu 8.04与库存记录(2.6.24.19)

7 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

**假设您没有使用O_SYNC或{{1}}

打开文件

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

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

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

顺便说一下。你在FAT32上测量写入性能吗?我猜它差不多,但如果没有,也许还有一些优化仍然可用?

答案 3 :(得分:1)

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

只是预感......带上一些盐:)

答案 4 :(得分:1)

可能会有所帮助 - Benchmarking Filesystems

  

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

"ext3 fsync batching"

  

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

答案 5 :(得分: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

答案 6 :(得分:-1)

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