Производительность записи на SD-карту - PullRequest
5 голосов
/ 10 октября 2008

Я пишу небольшое приложение, которое пишет изображения в формате JPEG с постоянной скоростью на SD-карте. Я выбираю файловую систему EXT3, но такое же поведение наблюдается с файловой системой EXT2.

Мой цикл записи выглядит так:

get_image()
fwrite()
fsync()

Или вот так:

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

Я также отображаю некоторую статистику по времени и вижу, что моя программа иногда блокируется на несколько секунд. Средняя скорость все еще хороша, потому что, если я сохраню входящие изображения в FIFO, то после такой остановки я напишу много изображений в короткий промежуток времени. Знаете ли вы, это проблема с ОС или это связано с самой SD-картой? Как я могу приблизиться к реальному времени? Мне не нужно сильное в реальном времени, но недолгая остановка на несколько секунд.

Некоторая точность: Да, fsync необходимо выполнять после каждого файла, потому что я хочу, чтобы изображение находилось на диске, а не в каком-либо буфере пользователя или ядра. Без fsyncing у меня намного лучше, но все равно недопустимый ларек. Я не думаю, что это проблема буфера, так как первый сбой происходит после того, как было записано 50 Мбайт. И, согласно man-странице, fsync здесь именно для того, чтобы гарантировать, что данные не буферизируются.

Точность относительно средней скорости записи: Я пишу со скоростью, устойчивой к карте, которую я использую. Если я собираю входящее изображение в ожидании завершения fsync, то после этой задержки скорость передачи записи увеличится, и я быстро вернусь к средней скорости. Средняя скорость передачи составляет около 1,4 МБайт / с .

Система представляет собой современный ноутбук под управлением Ubuntu 8.04 со стоковым Kee (2.6.24.19)

Ответы [ 7 ]

4 голосов
/ 20 января 2010

Попробуйте открыть файл с помощью O_DIRECT и выполнить кеширование на уровне приложения.

Мы столкнулись с подобной проблемой, когда реализовывали функцию PVR (Personal Video Record) в STB Box. Трюк O_DIRECT окончательно удовлетворил нашу потребность. (*)

Без O_DIRECT. Данные write() сначала будут кэшироваться в буфере ядра, а затем сбрасываться на носитель при вызове fsync или при заполнении буфера кэша ядра. (**).

При O_DIRECT. Ядро будет выполнять DMA непосредственно в физическую память, указанную буфером пространства пользователя, передаваемым в качестве параметра системным вызовам write. Таким образом, не будет расходоваться пропускная способность процессора и памяти в копиях между памятью пользовательского пространства и кэшем ядра, и не будет затрачиваться процессорное время в ядре на управление кэшем (например, поиск в кэше, блокировки страниц и т. Д.). (скопировано с здесь )

Не уверен, что это также может решить вашу проблему, но вы можете попробовать.

* Несмотря на то, что Линус критиковал из O_DIRECT, это решило наши проблемы.

** предположим, что вы не открыли файл с O_DSYNC или O_SYNC

3 голосов
/ 10 октября 2008

Нужно ли fsync() после каждого файла? Возможно, вам больше повезет, если вы решите, когда ОС выберет подходящее время для записи всех помещенных в очередь образов на SD-карту (амортизируя начальные затраты на манипулирование файловой системой SD-карты над многими изображениями, вместо того, чтобы использовать ее для каждого изображения).

Можете ли вы предоставить более подробную информацию о вашей платформе? Медленное время ввода-вывода может иметь отношение к другим процессам в системе, медленному контроллеру ввода-вывода и т. Д.

Вы также можете рассмотреть возможность использования файловой системы, более подходящей для работы флэш-памяти. FAT32 более распространен, чем extN, но файловая система, специально созданная для SD, также может быть в порядке. JFFS является хорошим примером этого. Вероятно, вы получите более высокую производительность с файловой системой, предназначенной для флэш-памяти (в отличие от вращающихся магнитных носителей), а также получите более качественные свойства выравнивания износа (и, следовательно, срока службы / надежности устройства).

2 голосов
/ 14 октября 2008

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

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

Btw. Вы измерили производительность записи на FAT32? Я предполагаю, что это примерно то же самое, но если нет, может быть, есть еще какая-то оптимизация?

1 голос
/ 12 января 2009

Может быть, это поможет - Сравнительный анализ файловых систем :

... Я был довольно удивлен, насколько медленным был ext3, так как многие дистрибутивы используют эту файловую систему в качестве файловой системы по умолчанию ...

И «ext3 fsync batching» :

... Этот патч измеряет время, необходимое для фиксации транзакции на диске, и спит в зависимости от скорости основного диска.

1 голос
/ 10 октября 2008

Я не очень хорошо осведомлен в этой области, но описанные вами симптомы звучат ужасно, как заполнение буфера. Возможно, вы заполняете буфер в устройстве записи файлов или в устройстве ввода-вывода, взаимодействующем с самой SD-картой. Затем вам нужно подождать, пока он фактически не записывает данные на карту (таким образом, опустошая буфер), прежде чем вы сможете записать больше. SD-карты не особенно быстрые писатели. Если вы сможете найти способ проверить, действительно ли данные записываются на карту во время этих пауз, это подтвердит мою теорию. У некоторых кард-ридеров есть светодиод, который мигает при доступе к данным - это, вероятно, будет хорошим индикатором.

Просто догадка ... возьми немного соли:)

0 голосов
/ 14 февраля 2014

Для любого, кто читает это и использует ядро ​​выше 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

0 голосов
/ 12 февраля 2009

Можно также рассмотреть SD-карту, это NOR или NAND? На этой странице показан порядок величины между картами SD (2M / s против 20M / s).
http://www.robgalbraith.com/bins/camera_multi_page.asp?cid=6007-9597
Я думаю, что ZFS оптимизирован для флэш-памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...