我正在录制音频并将其写入SD卡,数据速率约为1.5 MB / s。我正在使用带有ext4文件系统的4级SD卡。
在一定的间隔后,内核自动同步文件。这样做的缺点是,我的应用程序缓冲堆积等待写入磁盘。
我认为,如果内核经常同步它现在所做的事情,它可能会解决问题。
我在应用程序中使用fsync()
在某些间隔后进行同步。但这并没有解决问题,因为有些时候内核已经在应用程序调用{{1}}之前同步,所以从应用程序调用的fsync()是浪费时间。
我需要一个同步机制(比如fsync()
),这样当应用程序调用smart_fsync()时,内核只有在没有同步的情况下才会同步,否则它只会返回。
由于没有smart_fsync()
的功能。什么是可能的解决方法?
答案 0 :(得分:3)
要问的第一个问题是,你遇到的问题究竟是什么?内核会定期刷新脏(未写入的缓存)缓冲区 - 这是因为这样做比冲洗要快同步(应用程序的延迟时间减少)。缺点是,如果达到内核对脏数据的限制(以及在不干净关闭后可能导致更多数据丢失),这意味着更大的延迟命中。
如果您想确保数据尽快到达磁盘,那么您只需使用O_SYNC
选项打开该文件即可。这将在write()
后立即将数据刷新到磁盘。当然,这意味着显着的性能损失,但另一方面,您可以完全控制何时刷新数据。
如果在同步过程中遇到吞吐量下降,很可能您尝试写入的速度比磁盘可以支持的速度快,并且达到脏页内存限制。不幸的是,这意味着硬件根本没有达到你试图推动它的写入速率 - 你需要写得更慢,或者在更快的媒体上缓存数据(或者增加更多的RAM!)。
另请注意,您的'smart fsync'正是内核实现的内容 - 当满足以下条件之一时,它将刷新页面:
*内存中有太多脏数据。当脏数据总量超过/proc/sys/vm/dirty_background_bytes
时,或者当总内存的百分比超过/proc/sys/vm/dirty_background_ratio
时,异步触发(不阻止写入)。当数据总量超过write()
或总内存的百分比超过/proc/sys/vm/dirty_bytes
时,同步触发(长时间阻止应用程序的/proc/sys/vm/dirty_ratio
)。
*脏数据已在内存中待定太久。 pdflush
守护程序每隔/proc/sys/vm/dirty_writeback_centisecs
厘秒(1/100秒)检查旧脏块,如果它们在内存中的时间超过/proc/sys/vm/dirty_expire_centisecs
,则会使块过期。
调整这些参数可能会有所帮助,但你最好还要弄清楚为什么默认值不能保持原样。