Linux: умная fsync()?

Я записываю аудио и записываю то же самое на SD-карту, скорость передачи данных составляет около 1,5 МБ/с. Я использую SD-карту класса 4 с файловой системой ext4.

Через определенный интервал ядро ​​​​автоматически синхронизирует файлы. Недостатком этого является то, что мои буферы приложений накапливаются в ожидании записи на диск.

Я думаю, что если ядро ​​​​часто синхронизирует то, что оно делает сейчас, это может решить проблему.

Я использовал fsync() в приложении для синхронизации через определенные промежутки времени. Но это не решает проблему, потому что в определенные моменты ядро ​​​​синхронизировалось непосредственно перед вызовом приложения fsync(), поэтому вызов fsync() из приложения был пустой тратой времени.

Мне нужен механизм синхронизации (скажем, smart_fsync() ), чтобы, когда приложение вызывает smart_fsync(), ядро ​​синхронизировалось только в том случае, если оно не синхронизировалось какое-то время, иначе оно просто вернется.

Так как нет функции как smart_fsync(). какой может быть возможный обходной путь?


person user1702356    schedule 27.09.2012    source источник
comment
Я действительно не верю, что ядро ​​будет что-либо синхронизировать, если вы не превысите файловый буфер. Синхронизируя вручную (и довольно часто), вы можете сократить время каждой синхронизации, но в целом - затраченное время останется почти таким же. Вы также можете использовать неблокирующий ввод-вывод или поток записи, но это будет немного сложно. Кстати, 1,5 Мб для класса 4 — это очень мало. Отключение журнала FS может помочь.   -  person keltar    schedule 04.10.2012


Ответы (1)


Первый вопрос, который следует задать: в чем именно проблема, с которой вы столкнулись? Ядро будет периодически сбрасывать грязные (незаписанные в кэш) буферы. задержки для приложений). Недостатком является то, что это означает большую задержку, если вы достигнете предела ядра для грязных данных (и, возможно, большую потерю данных после нечистого завершения работы).

Если вы хотите, чтобы данные попали на диск как можно скорее, вам следует просто открыть файл с параметром O_SYNC. Это сбросит данные на диск сразу после write(). Конечно, это влечет за собой значительное снижение производительности, но, с другой стороны, вы полностью контролируете время сброса данных.

Если вы испытываете падение пропускной способности во время синхронизации, скорее всего, вы пытаетесь писать быстрее, чем может поддерживать диск, и достигаете предела памяти для грязных страниц. К сожалению, это будет означать, что аппаратное обеспечение просто не соответствует скорости записи, которую вы пытаетесь на него надавить — вам нужно будет писать медленнее или буферизовать данные на более быстром носителе (или добавить больше оперативной памяти!).

Заметьте также, что ваша «умная 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.

Возможно, настройка этих параметров может немного помочь, но вам, вероятно, лучше выяснить, почему значения по умолчанию не сохраняются такими, какие они есть.

person bdonlan    schedule 04.10.2012