Ruslan1 17 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба Про неочевидные вещи в 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() для адекватного общения с железом носителя большими блоками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба 11 minutes ago, Ruslan1 said: Выход: делать все преобразования вне FatFs библиотек, и использовать только f_read() и f_write() для адекватного общения с железом носителя большими блоками. А еще можно просто добавить дисковый кэш между FatFs и железом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба 1 hour ago, aaarrr said: А еще можно просто добавить дисковый кэш между FatFs и железом. Вы что-то делали в этом направлении? насколько трудоемко? У меня куча задач с доступом к диску (читают-пишут-создают-удаляют разные файлы), как-то не потянул я еще один уровень кэша добавлять снизу, а примеров в этом направлении не видел. Пока что ограничился кэшированием сверху- в задачах использую буферы по десятку килобайт, ну и только f_read и f_write, как выше написал. А наиболее агрессивные задачи на RAM диск пересадил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба Так там элементарно добавляется - в функции 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба 1 hour ago, Ruslan1 said: Вы что-то делали в этом направлении? насколько трудоемко? Делал когда-то, не для FatFs, да не суть. Ничего сложного. Кэш строится примерно так же, как в процессоре: чтение сектора вызывает заполнение строки (будет своего рода упреждающее чтение). Строки укладываются в односвязный список, обращение выносит строку на вершину, при промахе заполняется строка с хвоста. Отдельно формируется буфер записи достаточного размера, при сбросе буфера сектора в нем предварительно сортируются для оптимизации записи. Хорошо увязать кэш с менеджером памяти (если таковой имеется), и отдавать всё свободное ОЗУ под дисковый буфер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 16 июня, 2020 Опубликовано 16 июня, 2020 · Жалоба 3 hours ago, Ruslan1 said: Выход: делать все преобразования вне FatFs библиотек, и использовать только f_read() и f_write() для адекватного общения с железом носителя большими блоками. Юзайте ThreadX с FileX - https://github.com/azure-rtos/filex Там и кэши есть и exFAT c более быстрым поиском секторов и Fault Tolerant Support есть. И не будете знать проблем с доступом к файлам из множетсва задач. У меня много задач постоянно шуруют на SD кучу файлов с сенсоров, логи и временные файлы во время сессий с облаками. И проблем со скоростью очевидных не наблюдаю. Вы лучше скажите какую скорость хотите получить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 17 июня, 2020 Опубликовано 17 июня, 2020 (изменено) · Жалоба 19 часов назад, aaarrr сказал: А еще можно просто добавить дисковый кэш между FatFs и железом. А так как еще и "У меня куча задач с доступом к диску (читают-пишут-создают-удаляют разные файлы)," , а если "диск" - это СД карта или усб-флешка, то куча задач, особенно пишущих мелкие фрагменты ее просто убъют за короткое время... НО подумайте сразу о резервном питании устройства и быстром сбросе кэша на диск при откл. питания или все будет еще хуже, чем без кэша... 16 часов назад, AlexandrY сказал: У меня много задач постоянно шуруют на SD кучу файлов с сенсоров, логи и временные файлы во время сессий с облаками. "Бедные" у вас СДшки - наверно сразу как расходный материал Зачем все это на них писать, если есть "во время сессий с облаками"... Изменено 17 июня, 2020 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 30 minutes ago, mantech said: А так как еще и "У меня куча задач с доступом к диску (читают-пишут-создают-удаляют разные файлы)," , а если "диск" - это СД карта или усб-флешка, то куча задач, особенно пишущих мелкие фрагменты ее просто убъют за короткое время... А знаете, сколько смартфон пишет? Тем не менее, на несколько лет eMMC хватает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 17 июня, 2020 Опубликовано 17 июня, 2020 (изменено) · Жалоба 14 минут назад, aaarrr сказал: А знаете, сколько смартфон пишет? Тем не менее, на несколько лет eMMC хватает. И что? Хотите сказать, что там нет кэширования записи и он пишет по 60 байт каждый раз? Сколь бывал в сервисах - там замена этих самых ММС почти такая же частая операция, как и замена тача с аккумом... Изменено 17 июня, 2020 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 2 minutes ago, mantech said: Хотите сказать, что там нет кэширования записи и он пишет по 60 байт каждый раз? Есть, но все равно очень много пишет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 29 минут назад, aaarrr сказал: Есть, но все равно очень много пишет. Это я знаю, у меня только всегда вопрос по этому делу - зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 5 minutes ago, mantech said: зачем? Ну, раз на несколько лет хватает (т.е. существенно больше как гарантийного, так и среднего срока жизни изделия), то зачем утруждать себя оптимизацией? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 1 hour ago, mantech said: "Бедные" у вас СДшки - наверно сразу как расходный материал Зачем все это на них писать, если есть "во время сессий с облаками"... Проблема в RAM-е. RAM много жрет, поэтому в микропотребляющих IoT дивайсах RAM-а много не делают. А раз так, то все промежуточные результаты сжатия, кодирования, парсинга... все пишется и читаестя с SD карты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба Не хочу революцию. Пока что не готов менять FreeRTOS на другую, и даже FatFS на другое пока что. Мне достаточно вылизать свой код на предмет неиспользования f_puts и f_gets. Если идти дальше, то дополнительный кэш снизу может быть самым лучшим вариантом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 19 июня, 2020 Опубликовано 19 июня, 2020 · Жалоба 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться