repstosw 18 23 декабря, 2019 Опубликовано 23 декабря, 2019 (изменено) · Жалоба Добрый день. Проблема такая. Использую SD-карту по SPI (SDIO нет и не будет), перевожу её в High Speed mode, всё успешно: статус-регистры возвращаются как надо. Тактовая частота карты: 48 МГц. Прикрутил Fat FS ревизия 87030. Файлы видятся, работает чтение. Но скорость чтения данных с файлов не радует. 6 файлов общим объёмом 10 МБ читаются в течение 5,5 секунд. SD карты 4-го и 10-го класса скоростей на ёмкость 16 ГБ. Для чтения применяю мульти-секторную команду чтения (Read Begin, Read Data, Read End). Пробовал закешировать первый мегабайт (начальные сектора карты) - не помогает, видать файлы находятся дальше. Читаю с помощью fread() Какие есть пути (программные) повышения скорости чтения данных файлов? Нужно именно быстрое чтение данных, запись вообще не треуется. Изменено 23 декабря, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба А куда читаются файлы? Может, обработка содержимого файлов тормозит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 1 hour ago, __inline__ said: Какие есть пути (программные) повышения скорости чтения данных файлов? Кэширование с упреждающим чтением (строками, как процессор заполняет кэш). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 25 minutes ago, AHTOXA said: А куда читаются файлы? Может, обработка содержимого файлов тормозит? Читаются большими блоками в память. 17 minutes ago, aaarrr said: Кэширование с упреждающим чтением (строками, как процессор заполняет кэш). Применительно к секторам карты ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба Есть подозрение, что максимальные скорости доступны только по SDIO. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 2 minutes ago, jcxz said: Есть подозрение, что максимальные скорости доступны только по SDIO. Сравнивал время чтения файлов : в случае дефолтного режима (24 МГц) и High Speed (48 МГц) - соответственно 7 и 5,5 с. Поиск в интернете по "read ahead" толком ничего не находит. Ткните носом в существующие решения файлового кеша или дискового, изобретать велосипед как-то не хочется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 2 минуты назад, __inline__ сказал: Поиск в интернете по "read ahead" толком ничего не находит. Ткните носом в существующие решения файлового кеша или дискового, изобретать велосипед как-то не хочется. Насколько помню - там есть команды как посекторного чтения так и мультисекторного. Да и вообще разные команды. Какие используете? PS: А всё - вижу, не прочитал выше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jury093 2 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 8 минут назад, __inline__ сказал: Сравнивал время чтения файлов : в случае дефолтного режима (24 МГц) и High Speed (48 МГц) - соответственно 7 и 5,5 с. Поиск в интернете по "read ahead" толком ничего не находит. Ткните носом в существующие решения файлового кеша или дискового, изобретать велосипед как-то не хочется. при наличие свободной памяти смахните fat таблицу в память и попробуйте объяснить это fatfs, тут хоть немного будет ускорения при доступе к цепочке кластеров.. а вообще по однопроводке сильно быстро не будет, ваши 48МГц перемежаются старт-стопами spi и куча накладных расходов - проверьте сырую скорость считывания по интерфейсу и может проще будет сделать жесткую разбивку, допустим по 10МБ на файл при последовательном хранение с 0 сектора, а файлы обновлять через программную прослойку или через dd в линукс-машине Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 22 минуты назад, Jury093 сказал: тут хоть немного будет ускорения при доступе к цепочке кластеров.. а вообще по однопроводке сильно быстро не будет, ваши 48МГц перемежаются старт-стопами spi и куча накладных расходов Тоже хотел это сказать, мне больше 3мб\сек по 1 проводу не удавалось выбить даже из самой скоростной карты... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 16 минут назад, mantech сказал: Тоже хотел это сказать, мне больше 3мб\сек по 1 проводу не удавалось выбить даже из самой скоростной карты... Это можно быстро глянуть осциллом или лог.анализатором. Вангую - там даже при чтении последовательной цепочки секторов будут большие дырки из 0xFF-ок между данными на MISO. Тогда - только кешировать. На уровне секторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 23 декабря, 2019 Опубликовано 23 декабря, 2019 (изменено) · Жалоба 22 minutes ago, jcxz said: Это можно быстро глянуть осциллом или лог.анализатором. Вангую - там даже при чтении последовательной цепочки секторов будут большие дырки из 0xFF-ок между данными на MISO. Да, так оно и есть. львиная доля времени уходит на получение ответа готовности карты выдать ОЧЕРЕДНУЮ порцию данных по 512 байт. Хоть и мультисекторная команда. Код: DRESULT MMC_disk_read(BYTE* buff,DWORD sector,UINT count) { SDCARD_ReadBegin(sector); for(u32 i=0;i<count;i++)SDCARD_ReadData(&buff[i<<9]); SDCARD_ReadEnd(); return RES_OK; //all OK } s8 SDCARD_ReadBegin(u32 blockNum) { SDCARD_Select(); SDCARD_WaitNotBusy(); /* CMD18 (READ_MULTIPLE_BLOCK) command */ u8 cmd[] = { 0x40 | 0x12 /* CMD18 */, (blockNum >> 24) & 0xFF, /* ARG */ (blockNum >> 16) & 0xFF, (blockNum >> 8) & 0xFF, blockNum & 0xFF, (0x7F << 1) | 1 /* CRC7 + end bit */ }; SPI_TX((u8*)cmd,sizeof(cmd)); if(SDCARD_ReadR1() != 0x00) { SDCARD_Unselect(); return -2; } SDCARD_Unselect(); return 0; } s8 SDCARD_ReadEnd(void) { SDCARD_Select(); /* CMD12 (STOP_TRANSMISSION) */ { static const u8 cmd[] = { 0x40 | 0x0C /* CMD12 */, 0x00, 0x00, 0x00, 0x00 /* ARG */, (0x7F << 1) | 1 }; SPI_TX((u8*)cmd,sizeof(cmd)); } SPI(0xFF); if(SDCARD_ReadR1() != 0x00) { SDCARD_Unselect(); return -2; } SDCARD_Unselect(); return 0; } static inline s8 SDCARD_ReadData(u8* buff) { SDCARD_Select(); if(SDCARD_WaitDataToken(DATA_TOKEN_CMD18)<0) { SDCARD_Unselect(); return -1; } SDCARD_ReadBytes(buff,512); SPI(0xFF); SPI(0xFF); SDCARD_Unselect(); return 0; } static inline void SDCARD_ReadBytes(u8* buff, u32 buff_size) { while(buff_size>0) { *buff++=SPI(0xFF); buff_size--; } } Как видно, между полезными данными куча служебной лабуды... Интересную тему нашёл: https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=78105&page=1 То что описал уважаемый aarrrr - замечательно, в моём случае такой подход к кешированию поможет? Оперативной памяти под кеш могу до 8 МБ занять. Файлы читаю разом - крупным блоком сразу: открыл - считал - закрыл. Далее следующий файл... Файлов много (больше 10, меньше 100), есть папки с уровнем вложенности до 3, размер файлов 100 кБ - 20 МБ 36 minutes ago, mantech said: Тоже хотел это сказать, мне больше 3мб\сек по 1 проводу не удавалось выбить даже из самой скоростной карты... 3 мега-бита в секунду? Тогда 10 МБ должно открыться за 3,5 с, а не за 5,5 как в моём случае )) 59 minutes ago, Jury093 said: при наличие свободной памяти смахните fat таблицу в память и попробуйте объяснить это fatfs, тут хоть немного будет ускорения при доступе к цепочке кластеров.. а вообще по однопроводке сильно быстро не будет, ваши 48МГц перемежаются старт-стопами spi и куча накладных расходов - проверьте сырую скорость считывания по интерфейсу и может проще будет сделать жесткую разбивку, допустим по 10МБ на файл при последовательном хранение с 0 сектора, а файлы обновлять через программную прослойку или через dd в линукс-машине Есть ли способ быстро узнать стартовый сектор и размер таблицы FAT? Используется FAT32 с LFN Изменено 23 декабря, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jury093 2 23 декабря, 2019 Опубликовано 23 декабря, 2019 · Жалоба 2 часа назад, __inline__ сказал: Есть ли способ быстро узнать стартовый сектор и размер таблицы FAT? Используется FAT32 с LFN так проблема не в начальном доступе, а проблема организовать быстрое считывание цепочки кластеров, с заведомым ухудшением скорости при фрагментации файла. без кеширования у вас постоянно идет считывание секторов fat таблицы для поиска адреса очередного кластера. поищите, может есть отключение LFN, может даст минимальный прирост при обработке имен.. ЗЫ я в fat32 заглядывал лет 10 назад, когда к atmega прикручивал fat16 и целился подключить hdd. т.ч. больше знаний нет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 23 декабря, 2019 Опубликовано 23 декабря, 2019 (изменено) · Жалоба 4 часа назад, __inline__ сказал: 3 мега-бита в секунду? 2-3.5 мегабайта в сек, по среднему, где-то 2.5, на файлах поменьше, полтора мегабайта - это максимум, карта - трансенд, на всяких смартбаях еле до полутора дотягивало. 4 часа назад, __inline__ сказал: То что описал уважаемый aarrrr - замечательно, в моём случае такой подход к кешированию поможет? Кеширование файлов не поможет, ФС - возможно. Кеш файлов использовал только для распаковки картинок, т.к. в том же GIF требуется постоянное обращение за несколькими десятками байт - вот там кэш на 16-30Кбайт очень помог - скорость стала на порядок выше, с анимацией - еще больше, но если читать большие линейные куски - выигрыша нет совсем. Кэш заметно помогает при записи, но там своих проблем тоже не мало.. 4 часа назад, __inline__ сказал: Да, так оно и есть. львиная доля времени уходит на получение ответа готовности карты выдать ОЧЕРЕДНУЮ порцию данных по 512 байт. Ну, эт понятно, где-то и в стандарте про это писалось, там сначала из нанда идет выборка, потом всяческое буферирование и подсчет всяких КС, и только потом выдача в порт. ЗЫ, да и по 512 байт уже давно никто не читает, 4К - сейчас это минимум.. Изменено 23 декабря, 2019 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 24 декабря, 2019 Опубликовано 24 декабря, 2019 · Жалоба 7 hours ago, mantech said: ЗЫ, да и по 512 байт уже давно никто не читает, 4К - сейчас это минимум.. Не могли бы вы осветить этот момент подробнее? Пробовал читать больше чем по 512 байт: по 1024 и по 4096 - файловая система работает некорректно с такими длинами чтений. Интересует SDCARD_ReadData(u8* buff) Там после каждых 512 байт надо делать опрос SDCARD_WaitDataToken(DATA_TOKEN_CMD18)<0) , иначе неправильно работает. Прорабатываю вариант без LFN, имена директорий и файлов в формате 8.3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 24 декабря, 2019 Опубликовано 24 декабря, 2019 · Жалоба 1 hour ago, __inline__ said: Прорабатываю вариант без LFN, имена директорий и файлов в формате 8.3 Прироста в скорости переход с LFN на 8.3 не дал. Флажок в ffconf LFN выставлен в 0. Тут пишут, что мультиблочное чтение всёравно должно идти порциями по 512 байт и нужно ждать дата-токена и считывать 2 байта CRC. Разом не считаешь без дата-токена - нужно ждать. А это плохо. https://www.avrfreaks.net/forum/writeread-multiple-blocks-sd-card-0 Read multiple blocks is same as above except: Send READ_MULTIPLE_BLOCK command to card with address, number of blocks etc Repeat for number of blocks { Poll card for 0xFE (data token) Receive the 512 bytes. receive 2 CRC bytes } + READ END CMD Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться