Перейти к содержанию
    

Оптимизация доступа в FatFs: дьявол в деталях.

Про неочевидные вещи в FatFs. Кому-то это может и очевидно, но я сколько-то времени убил на осознание масштабов проблемы. Оставлю здесь, вдруг кому еще поможет.

Про оптимизацию доступа к диску при многозадачности, когда много задач периодически лезут на диск по разным нуждам. Я тренировался на SD карточке, но касается любого носителя.

 

Как бы Вы ни пытались оптимизировать доступ к диску, есть несколько внутренних функций, применение которых может очень сильно огорчить. Эти функции разбивают вроде бы одно цельное действие на гарантированно большое количество коротких доступов к диску. В результате происходит постоянная перезагрузка контента и внутренних кэшей SD карточки. Я про функции-обертки FatFs, которые внутри себя вызывают f_read() и f_write(). Но вот общаются они с диском уже маленькими порциями, так что любые потуги на организацию блочного чтения/записи в собственно драйвере нижнего уровня выгладят смешно и бесполезно.

Например:

f_puts() - обрабатывает данные маленькими порцийками, и передает в f_write()  данные максимум по 62 байта.

f_gets() - читает через f_read() по 1 или 2 или 3 или 4 байта, а не строками.

Думаю, список таких функций-тормозов можно продолжить.

Выход: делать все преобразования вне FatFs библиотек, и использовать только f_read() и f_write() для адекватного общения с железом носителя большими блоками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 minutes ago, Ruslan1 said:

Выход: делать все преобразования вне FatFs библиотек, и использовать только f_read() и f_write() для адекватного общения с железом носителя большими блоками.

А еще можно просто добавить дисковый кэш между FatFs и железом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, aaarrr said:

А еще можно просто добавить дисковый кэш между FatFs и железом.

Вы что-то делали в этом направлении? насколько трудоемко?

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

Пока что ограничился кэшированием сверху- в задачах использую буферы по десятку килобайт, ну и только f_read и f_write, как выше написал. А наиболее агрессивные задачи на RAM диск пересадил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так там элементарно добавляется - в функции disk_read() добавить поиск сектора в списке сохранённых, а в disk_write() - сохранение в кэш.

Я так делал, когда у меня fatfs читал карточку по UART :-)

Типа:

DRESULT disk_read(BYTE drv, BYTE *buf, DWORD sector, BYTE sectorCount)
{
	if (!sectorCount) return RES_PARERR;
	if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;

	if (sectorCount!=1)  // кэшируем только одиночные сектора
		return (sdioCore.ReadBuffer(buf, sector, sectorCount) == ERROR_NO_ERROR) ? RES_OK : RES_ERROR;
	
	if (cache.get(sector, buf))  // нашли в кэше?
		return RES_OK;

	if (sdioCore.ReadBuffer(buf, sector, sectorCount) == ERROR_NO_ERROR)
	{
		cache.put(sector, buf);
		return RES_OK;
	}
	return RES_ERROR;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Ruslan1 said:

Вы что-то делали в этом направлении? насколько трудоемко?

Делал когда-то, не для FatFs, да не суть. Ничего сложного. Кэш строится примерно так же, как в процессоре: чтение сектора вызывает заполнение строки (будет своего рода упреждающее чтение). Строки укладываются в односвязный список, обращение выносит строку на вершину, при промахе заполняется строка с хвоста. Отдельно формируется буфер записи достаточного размера, при сбросе буфера сектора в нем предварительно сортируются для оптимизации записи. Хорошо увязать кэш с менеджером памяти (если таковой имеется), и отдавать всё свободное ОЗУ под дисковый буфер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Ruslan1 said:

Выход: делать все преобразования вне FatFs библиотек, и использовать только f_read() и f_write() для адекватного общения с железом носителя большими блоками.

Юзайте ThreadX с FileX - https://github.com/azure-rtos/filex
Там и кэши есть и exFAT c более быстрым поиском секторов и Fault Tolerant Support есть.
И не будете знать проблем с доступом к файлам из множетсва задач. 
У меня много задач постоянно шуруют на SD кучу файлов с сенсоров, логи и временные файлы во время сессий с облаками.  
И проблем со скоростью очевидных не наблюдаю. 
Вы лучше скажите какую скорость хотите получить. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 часов назад, aaarrr сказал:

А еще можно просто добавить дисковый кэш между FatFs и железом.

А так как еще и "У меня куча задач с доступом к диску (читают-пишут-создают-удаляют разные файлы)," , а если "диск" - это СД карта или усб-флешка, то куча задач, особенно пишущих мелкие фрагменты ее просто убъют за короткое время... НО подумайте сразу о резервном питании устройства и быстром сбросе кэша на диск при откл. питания или все будет еще хуже, чем без кэша...

16 часов назад, AlexandrY сказал:

У меня много задач постоянно шуруют на SD кучу файлов с сенсоров, логи и временные файлы во время сессий с облаками.  

"Бедные" у вас СДшки - наверно сразу как расходный материал :biggrin: Зачем все это на них писать, если есть "во время сессий с облаками"...

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 minutes ago, mantech said:

А так как еще и "У меня куча задач с доступом к диску (читают-пишут-создают-удаляют разные файлы)," , а если "диск" - это СД карта или усб-флешка, то куча задач, особенно пишущих мелкие фрагменты ее просто убъют за короткое время...

А знаете, сколько смартфон пишет? Тем не менее, на несколько лет eMMC хватает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, aaarrr сказал:

А знаете, сколько смартфон пишет? Тем не менее, на несколько лет eMMC хватает.

И что? Хотите сказать, что там нет кэширования записи и он пишет по 60 байт каждый раз? Сколь бывал в сервисах - там замена этих самых ММС почти такая же частая операция, как и замена тача с аккумом...

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, mantech said:

Хотите сказать, что там нет кэширования записи и он пишет по 60 байт каждый раз?

Есть, но все равно очень много пишет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 минут назад, aaarrr сказал:

Есть, но все равно очень много пишет.

Это я знаю, у меня только всегда вопрос по этому делу - зачем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, mantech said:

зачем?

Ну, раз на несколько лет хватает (т.е. существенно больше как гарантийного, так и среднего срока жизни изделия), то зачем утруждать себя оптимизацией?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, mantech said:

"Бедные" у вас СДшки - наверно сразу как расходный материал :biggrin: Зачем все это на них писать, если есть "во время сессий с облаками"...

Проблема в RAM-е.
RAM много жрет, поэтому в микропотребляющих IoT дивайсах RAM-а много не делают.

А раз так, то все промежуточные результаты сжатия, кодирования, парсинга... все пишется и читаестя с SD карты.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не хочу революцию. Пока что не готов менять FreeRTOS на другую, и даже FatFS на другое пока что. Мне достаточно вылизать свой код на предмет неиспользования f_puts и f_gets.

Если идти дальше, то дополнительный кэш снизу может быть самым лучшим вариантом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 6/16/2020 at 9:30 PM, AlexandrY said:

Юзайте ThreadX с FileX - https://github.com/azure-rtos/filex
Там и кэши есть и exFAT c более быстрым поиском секторов и Fault Tolerant Support есть.
И не будете знать проблем с доступом к файлам из множетсва задач. 
У меня много задач постоянно шуруют на SD кучу файлов с сенсоров, логи и временные файлы во время сессий с облаками.  
И проблем со скоростью очевидных не наблюдаю. 
Вы лучше скажите какую скорость хотите получить. 

Вижу вы используете FileX, поделитесь впечатлениями, хотелось бы подробностей. Описание впечатляет. Но смущает что на github ни одного бага в Issues, такое впечатление что мало кто использует.

Сейчас использую LittleFS, надоело, куча критичных багов в Issues, при большом количестве файлов или когда много перезаписей - создание/открытие нового файла занимает очень много времени, срабатывает вочдог. Хочу от нее уйти. Но голая FatFs тоже не подходит, от файловой системы нужны устойчивость к сбоям питания и выравнивания износа для работы на SPI FLASH 8 MB. Ну и чтобы для этого не нужно было 128 KB RAM.

Вроде все это заявлено FileX с FAULT_TOLARANCE, LevelX оттуда же для выравнивания изности. Не нашел только требования к RAM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...