|
FatFs на STM32 - кеширование FAT32?, чтобы ускорить f_open() |
|
|
|
Jul 5 2010, 22:01
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 6 2010, 01:51)  Нет, это не совсем так. Во-первых, читаем не по одному сектору, что уже дает преимущество в скорости (причем иногда в разы). Во-вторых, вы упускаете чтение собственно FAT. Если же речь идет о чтении корневого каталога FAT16, то его длина обычно составляет 16кбайт, что позволяет спокойно разместить его даже в памяти STM32. Речь о FAT32. А для чего читать FAT, разве добраться до записи с информацией о файле (с именем и первым сектором) нельзя просто последовательно читая каталог? Если, кроме каталога, читаются ещё и другие сектора - тогда это только увеличивает требования к размеру кеша...
|
|
|
|
|
Jul 5 2010, 22:15
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 6 2010, 02:01)  А для чего читать FAT, разве добраться до записи с информацией о файле (с именем и первым сектором) нельзя просто последовательно читая каталог? А как последовательно читать каталог, не читая при этом FAT? Каталог - это тот же файл, за исключением случая корневого каталога FAT12/16. Цитата(sonycman @ Jul 6 2010, 02:01)  Если, кроме каталога, читаются ещё и другие сектора - тогда это только увеличивает требования к размеру кеша... FAT нужно будет читать при переходе на каждый следующий кластер файла, то есть данные FAT не будут выведены из кэша, если только его размер превышает размер одного кластера диска. Таким образом кэш размером 20кбайт вполне может быть полезен.
|
|
|
|
|
Jul 5 2010, 23:44
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Получил результаты своего отладочного логгера, который сохранил историю запросов на чтение диска при работе функции f_open(). Цифры - LBA сектора в шестнадцатеричном виде: CODE 00004000 00004001 00004002 00004003 00004004 00004005 00004006 00004007 00004008 00004009 0000400a 0000400b 0000400c 0000400d 0000400e 0000400f 00004010 00004011 00004012 00004013 00004014 00004015 00004016 00004017 00004018 00004019 0000401a 0000401b 0000401c 0000401d 0000401e 0000401f 00004020 00004021 00004022 00004023 00004024 00004025 00004026 00004027 00004028 00004029 0000402a 0000402b 0000402c 0000402d 0000402e 0000402f 00004030 00004031 00004032 00004033 00004034 00004035 00004036 00004037 00004038 00004039 0000403a 0000403b 0000403c 0000403d 0000403e 0000403f 0000386c 00004040 00004041 00004042 00004043 00004044 00004045 00004046 00004047 00004048 00004049 0000404a 0000404b 0000404c 0000404d 0000404e 0000404f 00004050 00004051 00004052 00004053 00004054 00004055 00004056 00004057 00004058 00004059 0000405a 0000405b 0000405c 0000405d 0000405e 0000405f 00004060 00004061 00004062 00004063 00004064 00004065 00004066 00004067 00004068 00004069 0000406a 0000406b 0000406c 0000406d 0000406e 0000406f 00004070 00004071 00004072 00004073 00004074 00004075 00004076 00004077 00004078 00004079 0000407a 0000407b 0000407c 0000407d 0000407e 006006c0 006006c1 006006c2 006006c3 006006c4 006006c5 006006c6 006006c7 006006c8 006006c9 006006ca 006006cb 006006cc 006006cd 006006ce
Кластер на карточке равен 32 килобайтам. Как видно, чтобы открыть файл, считывается два с лишним кластера каталогов (!!!) (а между ними проскакивает сектор FAT?). И так практически для всех 57 файлов папки, а если точнее - методом односекторного чтения считывается 131 сектор для первого файла, и уже 143 сектора для последнего. Хм, действительно, если читать сразу по 8 секторов за раз, то можно несколько выиграть.  ЗЫ: завтра посмотрю, какая картина будет при сортировке 500 файлов. Аж страшно становится ЗЗЫ: до чего убогая файловая система, господи. Чтобы добраться до грошового файлика весом в сотню байт, требуется перерыть килобайты мусора в виде каталогов...
|
|
|
|
|
Jul 6 2010, 09:11
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(sonycman @ Jul 6 2010, 03:09)  А как же мультисекторные чтение/запись? Нет, конечно-же, не пугайте так  Эта функция используется только в конфигурации _FS_TINY. В остальных случаях идёт прямое обращение к disk_read() - к драйверу. Да, действительно. Видимо я ковырял очень старую версию FatFs, где ещё не было мультисекторного чтения/записи. Или просто что-то перепутал Цитата Привыкли, наверное, к AVR? Вы меня наверное с кем-то путаете?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 6 2010, 10:24
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(AHTOXA @ Jul 6 2010, 13:11)  Вы меня наверное с кем-то путаете? Показалось просто. Извините Прогнал сортировщик на файлах в другой папке, общим количеством в 500. Первый файл - 129 секторов каталога, похоже на предыдущий скан. Зато вот последний: CODE 00004000 00004001 00004002 00004003 00004004 00004005 00004006 00004007 00004008 00004009 0000400a 0000400b 0000400c 0000400d 0000400e 0000400f 00004010 00004011 00004012 00004013 00004014 00004015 00004016 00004017 00004018 00004019 0000401a 0000401b 0000401c 0000401d 0000401e 0000401f 00004020 00004021 00004022 00004023 00004024 00004025 00004026 00004027 00004028 00004029 0000402a 0000402b 0000402c 0000402d 0000402e 0000402f 00004030 00004031 00004032 00004033 00004034 00004035 00004036 00004037 00004038 00004039 0000403a 0000403b 0000403c 0000403d 0000403e 0000403f 0000386c 00004040 00004041 00004042 00004043 00004044 00004045 00004046 00004047 00004048 00004049 0000404a 0000404b 0000404c 0000404d 0000404e 0000404f 00004050 00004051 00004052 00004053 00004054 00004055 00004056 00004057 00004058 00004059 0000405a 0000405b 0000405c 0000405d 0000405e 0000405f 00004060 00004061 00004062 00004063 00004064 00004065 00004066 00004067 00004068 00004069 0000406a 0000406b 0000406c 0000406d 0000406e 0000406f 00004070 00004071 00004072 00004073 00004074 00004075 00004076 00004077 00004078 00004079 0000407a 0000407b 0000407c 0000407d 0000407e 00612980 00612981 00612982 00612983 00612984 00612985 00612986 00612987 00612988 00612989 0061298a 0061298b 0061298c 0061298d 0061298e 0061298f 00612990 00612991 00612992 00612993 00612994 00612995 00612996 00612997 00612998 00612999 0061299a 0061299b 0061299c 0061299d 0061299e 0061299f 006129a0 006129a1 006129a2 006129a3 006129a4 006129a5 006129a6 006129a7 006129a8 006129a9 006129aa 006129ab 006129ac 006129ad 006129ae 006129af 006129b0 006129b1 006129b2 006129b3 006129b4 006129b5 006129b6 006129b7 006129b8 006129b9 006129ba 006129bb 006129bc 006129bd 006129be 006129bf 00003b73 006129c0 006129c1 006129c2 006129c3 006129c4 006129c5 006129c6 006129c7 006129c8 006129c9 006129ca 006129cb 006129cc 006129cd 006129ce 006129cf 006129d0 006129d1 006129d2 006129d3 006129d4 006129d5 006129d6 006129d7 006129d8 006129d9 006129da 006129db 006129dc 006129dd 006129de 006129df 006129e0 006129e1 006129e2 006129e3 006129e4 006129e5 006129e6 006129e7 006129e8 006129e9 006129ea 006129eb 006129ec 006129ed 006129ee 006129ef 006129f0 006129f1 006129f2 006129f3 006129f4 006129f5 006129f6 006129f7 006129f8 006129f9 006129fa 006129fb 006129fc 006129fd 006129fe
это вообще жесть - 256 секторов, четыре полных кластера! Попробую сделать простой кеш в виде считывания при любом запросе сразу 8 секторов. Отводить 20 килобайт не вижу смысла - огромное количество запрашиваемых секторов в них разместить никак не получится. Отведу память чисто под эти 8 секторов, и всё. Посмотрим, какие будут результаты...
|
|
|
|
|
Jul 12 2010, 21:47
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 13 2010, 01:41)  Подобное решение хоть и возможно теоретически, но весьма значительно усложнит реализацию файловой системы. Как минимум придется соорудить еще один кэш для цепочки FAT просматриваемого каталога. Не стоит это того. Если нужен нормальный кеш - надо ставить много памяти. Простым чтением по запросу MoveWindow() вместо одного сектора - сразу восьми, я получил выигрыш в скорости в 20%. Не бог весть что, но тоже результат, с учётом всего лишь 4 килобайт отведённой под такой кеш памяти
|
|
|
|
|
Jul 12 2010, 22:52
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 13 2010, 01:47)  Не стоит это того. Если нужен нормальный кеш - надо ставить много памяти. Это верно. Совсем недавно пришлось в одном проекте выделить под кэш 4 мегабайта, так как каталог может содержать 100 тысяч файлов с именами вида: XX000000.XXX XX000001.XXX До кучи было добавлено битовое поле на 100 кбит, чтобы быстро выяснять наличие файла с произвольным номером. Грубо, зато просто и эффективно. Цитата(sonycman @ Jul 13 2010, 01:47)  Простым чтением по запросу MoveWindow() вместо одного сектора - сразу восьми, я получил выигрыш в скорости в 20%. Не бог весть что, но тоже результат, с учётом всего лишь 4 килобайт отведённой под такой кеш памяти  А не собирали статистику, сколько из этих восьми идет впрок?
|
|
|
|
|
Aug 23 2010, 01:41
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(Ivan Kuznetzov @ Aug 23 2010, 00:20)  извиняюсь за оффтоп, sonycman, как у Вас объявлена структура FATFS fs; ? как глобальная? или в процедуре main()? у меня возникла интересная проблемка: когда эта структура объявлена глобально, запись в файл глючит, а именно, при записи в файл первый элемент байтового массива искажается процедурой f_write. (байтовый массив объвлен глобально). Именно глобально. Наверное, у Вас какая то накладочка выходит с массивом или со стеком, f_write() тут не при чём, имхо.
|
|
|
|
|
Aug 25 2010, 17:56
|

Местный
  
Группа: Свой
Сообщений: 307
Регистрация: 6-02-08
Из: Россия, Екатеринбург
Пользователь №: 34 798

|
Цитата(sonycman @ Aug 23 2010, 07:41)  Именно глобально. Наверное, у Вас какая то накладочка выходит с массивом или со стеком, f_write() тут не при чём, имхо. массив из 512 байт тоже объявлен глобально. Если объявляю FATFS fs глобально, а массив data[512] запихиваю в функцию - начинает работать нормально, тоесть меняю местами. если всё делаю глобально - опять косяк, после f_write содержимое первого байта массива меняетя. Именно после того, как мы записываем массив на карту командой f_write (смотрю дебаггером), первый байт становится красненьким ... файловый объект FIL file; у меня объявлен глобально, это правильно?
--------------------
Разработчик
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|