Если кто то следил за хронологией сайта, то уже два года прошло как появилась статья про либу FAT от Чена, с тех пор постоянно пользуюсь ей в разных проектах. Сказать по правде, часто слышу что она такая глючная и плохая, но за все это время использования не припомню никаких проблем. Продолжение истории не очень интересное, зато интересен финал.

Хотел было применить в очередной раз данную либу, но внезапно столкнулся с утверждением мол пользоваться либой это плохо. Рассуждения относительно самой либы нам сейчас не интересны, холивар оставим за бортом. Ее внутренностям обязательно будет уделено отдельное время, где мы подробно все рассмотрим в деталях и все будет расставлено по местам.

Важно то, что всплыл интересный факт, если постоянно писать в один и тот же сектор, то скорость записи примерно через 60 циклов резко падает. Поэтому нужно было разобраться действительно ли это так.

Итак какую информацию можно нарыть в инете на этот счет? Как мы помним флеш память имеет небольшой ресурс записи, поэтому если писать в один и тот же сектор, то он может быстро сдохнуть. Обычно производители заявляют ресурс в 10000 циклов перезаписи. Думаю эта инфа известна всем, а вот дальше мнения разделились:

Мнение 1. Контроллер карты памяти тупой, куда ему скажешь писать туда он и запишет. Поэтому если вы разом жахните по одному и тому же адресу 10000 циклов перезаписи, то карта тут же сдохнет.

Мнение 2. Контроллер карты умный. Для того, чтобы сектора равномерно изнашивались, контроллер карты памяти переносит сектора, т.е. на самом деле, когда мы пишем по какому то адресу на карту, то данные пишутся не в физический адрес, а в логический. В моменты переноса, как и было утверждение выше, длительность времени записи резко увеличивается. Но тут мнения еще раз разделились: 1. контроллер переносит сектора, только если их некий внутренний «счетчик записи сектора» перевалил определенное значение. 2. контроллер постоянно переносит сектора, не зависимо ни от каких факторов.

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

У меня под рукой было две карты памяти — первая Transcend, название производителя, второй карты я не помню, важно что она не из дешевых, будем называть ее Noname. Поэтому сразу оговорюсь, результаты действительны только именно для двух этих карт.
sd

Все тесты проводились на скорости 4МБит/с по интерфейсу SPI. Все операции производились командами карты памяти: стирание (CMD32, CMD33, CMD38), чтение(CMD17), запись(CMD24). Грубая прикидка: скорость 4 МБита/сек = 500 кБайт/сек. В секторе 512байт + 48байт на команду, т.е. все это дело должно улететь чуть более 0,00112сек. Естественно что ожидаемая скорость будет ниже, самый главный вопрос на сколько?

Придумалось 3 теста: 1.пишем в один и тот же сектор, постоянно стирая его. 2. стираем сектор, но пишем в следующий адрес(хотелось понять влияет ли как то стирание) 3. постоянно пишем в новый сектор(в адрес +1), ничего не стирая.

Что еще важно знать? То что если в сектор уже что то записано, то «поверх» записать нельзя, команда выполнится, но новые данные вы не увидите. Перед тем как записать обязательно сначала стереть. Поэтому все карты были полность отформатированы до начала каждого из тестов.

Переходим к делу. Исходники приводить не буду, ибо тут итак все понятно. Перед каждой из операций, обнуляю переменные и запускаю таймер. По завершению операции, таймер останавливается, считывается его значение, на всякий случай смотрю было ли переполнение. Результат в буфер. Накопленный буфер скидываю на комп, где через самопальную утилиту перегоняю данные в Excel файл, где уже удобно строить графики.

Тест 1. Цикл состоит из:
1.Стирание
2.Запись
3.Чтение
4.Проверка записанного сектора
5.Замера времени каждого из этих действий
Количество циклов 5000

Сразу смотрим графики записи. Они не в одном масштабе, но уловить смысл можно.
Noname
prom_write_5000

Transcend
transcend_write_5000

Что мы видим? У трансенда есть некий «выброс» в начале теста, который в 18 раз превышает среднюю скорость записи. В дальнейшем все устаканивается, но скорость постоянно скачет. Могут ли это быть те самые перемещения секторов? Возможно, но наверняка знает только производитель карт памяти. У нонейма все более стабильно, скорость скачет постоянно, но на одни и те же величины, через примерно одинаковые интервалы. Возможно это связано с тем, что трансенд уже был не молод к началу теста, а нонейм был вытащен из коробки новый. Самое интересное другое — если рассматривать среднюю скорость, то не смотря на выброс, транс показал 7мс, а нонейм 8мс.

Тест 2. Цикл состоит из:
1.Стирание сектора
2.Запись в следующий сектор
3.Чтение
4.Проверка записанного и прочитанного
5.Замера времени каждого из этих действий
Количество циклов 1000

Noname
prom_write_next_1000

Transcend
transcend_write_next_1000

Казалось бы картина немного изменилась, теперь мы не долбимся в один и тот же сектор. Но при подсчете средней скорости, все оказалось иначе обе карты показали 7мс, таким образом, что мы стираем один и тот же сектор, что разные это никак не влияет на скорость.

И наконец, тест 3. Цикл состоит из:
1.Запись в следующий сектор
3.Чтение
4.Проверка записанного и прочитанного
5.Замера времени каждого из этих действий
Количество циклов 1000

Noname
prom_write2_noerase

Transcend
transcend_write2_noerase_1000

И опять таки чудеса с трансендом, даже не смотря на отсутствие стирания, карта выдает зависоны которые в 10 раз превышают среднюю скорость записи. Тем не менее, скорость записи и одной, и второй карты возросла аж в 2 раза!!! В среднем 3мс!!!

Полученные результаты можно наблюдать в таблице.
Transcend

Тест 1 Тест 2 Тест 3
Скорость Запись Чтение Запись Чтение Запись Чтение
Минимум, сек 0.00619 0.00563 0.00625 0.00575 0.00363 0.00569
Максимум, сек 0.11025 0.08913 0.02581 0.04638 0.04825 0.07419
Средняя, сек 0.00741 0.00664 0.00739 0.00594 0.00382 0.00734

Noname

Тест 1 Тест 2 Тест 3
Скорость Запись Чтение Запись Чтение Запись Чтение
Минимум, сек 0.00725 0.00663 0.00694 0.00663 0.00363 0.00538
Максимум, сек 0.01963 0.01713 0.04756 0.03988 0.00713 0.0170
Средняя, сек 0.00852 0.00796 0.00744 0.00710 0.00372 0.0068

Итак, какие же выводы можно сделать. Во первых, заниматься стиранием/форматированием карты памяти нужно как можно реже. Если пытаться объяснить те периодические выбросы, в том числе и на последних графиках, то можно предположить, что контроллер занимается перемещением секторов постоянно, не зависимо ни от чего. Косвенно это подтверждается тем, что в один и тот же сектор я записывал более 50000 раз и обе карты не сдохли и живы по сей день.

5 комментариев: Тесты скорости SDHC карт памяти

  • Молодец автор! Теперь буду знать… Интересно, а в микроконтроллерах FLASH-память также работает? Тоже сектора переносятся? А то я бывает, чтобы программка работала чётко, стираю и перепрограммирую много раз…

  • Получается, что только контроллер знает, где физически находится данный сектор…

  • Интересно, а как тогда восстанавливают информацию с бортовых самописцев (разрушенных)? Там ведь тоже запись идет во флеш-память?

  • В микроконтроллерах вряд ли также, ресурс перепрограммированием сложно исчерпать — проверено. Про перенос секторов речь идет только для SD карт, да и как было сказано наверняка знает только производитель.

  • Денис, на данный момент распространены 2 типа флеши: NOR и NAND.
    Первая является очень надежной и используется как раз таки для хранения прошивок во всяких МК. Так же встречается в качестве отдельных чипов: 25-я память с SPI и 29-я с параллельной шиной.
    Минусом NOR являются небольшие объемы, до 16-ти МБ для SPI микрух, но перезаписывать их можно десятки тыс. раз и память на них хранится до сотни лет. Физически NOR — это один слой транзисторов.
    NAND же представляет собой многослойную конструкцию, где более того — приоритет отдан объемам, а не надежности вплоть до каждого бита каждого сектора. Ну, и в итоге получаем: десятки гигабайт на одном чипе, но который не может работать без промежуточного контроллера, который бы постоянно проверял ошибки и переназначал умершие сектора. 😉

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика