[Из песочницы] USB-флешки: заряжать нельзя игнорировать

rpllgzumaroc_k6ffkgdy2weca0.jpeg

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

Пара ссылок по теме:


Я, конечно, поржал, но не над тем, над чем вы подумали. Мне приходилось принимать участие в разработке твердотельных накопители на основе NAND-flash памяти, в том числе и для USB-флешек. На первый взгляд для технически подкованного человека кажется очевидным, что подключение накопителя к заряднику бессмысленно, так как кроме подачи питания никаких прочих действий с накопителем не производится, поэтому, кроме тепловыделения мы ничего не получим. В интернете много разных «разоблачений», смешков и даже откровенного стеба над бедными гуманитариями, которые спрашивают, стоит ли заряжать флешки. Можете смеяться, но я видел своими глазами, как разработчики флешек именно «заряжали» свои изделия, устанавливая их в зарядники на некоторое время!

USB-флешка является блочным устройством хранения данных: все адресное пространство разбито на секторы по 512 байт. Операционная система может обратиться по адресу определенного сектора (LBA) и прочитать его или перезаписать, все просто.

А теперь заглянем под капот нашей флешки…

В состав флешки входят микросхемы:

  • контроллер;
  • NAND-flash память.


Микросхемы памяти устроены довольно специфично с точки зрения адресации, записи и хранения данных, что продиктовано ее архитектурой (и мы должны любить ее такой, какая она есть). Для NAND-flash определены следующие правила:

  • Память разделена на блоки, размером порядка единиц Мегабайт;
  • Перед записью в блок памяти его необходимо стереть. При стирании все байты данных в блоке устанавливаются в значение 0xFF;
  • Блок состоит из страниц, размером порядка десятков Килобайт;
  • Запись данных в блок производится страницами, одновременно может быть записана сразу вся страница данных;
  • Страницы данных внутри одного блока должны записываться строго в порядке возрастания их номеров;
  • Каждая страница после стирания блока может быть записана только единожды до следующего стирания.


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

rha--yse73m6ydblmudfn9ipycs.jpeg

Попробуйте представить, как бы эту задачку решили вы, и увидите сходство с игрушкой «Ханойская башня» (https://ru.wikipedia.org/wiki/%D0%A5%D0%B0%D0%BD%D0%BE%D0%B9%D1%81%D0%BA%D0%B0%D1%8F_%D0%B1%D0%B0%D1%88%D0%BD%D1%8F).

Для того, чтобы «подружить» user-friendly блочную адресацию накопителя и sadist-friendly адресацию NAND-flash памяти, внутри контроллера флешки крутится процессор, который реализует алгоритм трансляции адресов, он же FTL (Flash Translation Layer). В задачи алгоритма FTL входят:

  • построение и поддержка таблицы трансляции адресов (page mapping);
  • «сборка мусора» (garbage collection);
  • выравнивание износа блоков NAND-flash памяти (wear leveling).


Знающие люди скажут, что есть еще и другие задачи, как, например, отслеживание битых блоков NAND-flash памяти (bad block management), но я об этом сейчас не хочу говорить, потому что к текущему делу не относится…

Немного ликбеза по обозначенным пунктам:

Page mapping


Ну, тут, пожалуй, все понятно… Адресное пространство логических адресов накопителя (LBA) транслируется в адреса блоков и страниц NAND-flash памяти (физический адрес) через огромный массив, индекс которого означает LBA, а значение элемента — физический адрес. Если необходимо перезаписать одну страаницу, то данные этой страницы пишутся в свободный блоки по порядку, а, затем, в массиве заменяется номер страници на вновь записанный. Когда школьник покупает флешку 32ГБайта, а обнаруживает, что на ней только 29 ГБайт, школьник еще не знает, что недостающее место не китайцы на фабрике украли, а разработчики алгоритма FTL. Чтобы иметь возможность писать данные на накопитель.

5_o2ws6yyfhv0i6ulgbmhyskggu.png

Garbage Collection


А что будет со страницей, которая утратила актуальность? Данные, записанные в ней больше не нужны, но стереть ее мы не сможем, потому что стирать дозволено только блоками, а в этом же блоке могут быть еще актуальные страницы. Рано или поздно сложится ситуация, когда у нас больше нет свободных блоков, в которые можно писать страницы. Зато, в остальных блоках то там, то сям будут неактуальые страницы. Чтобы такого не случилось, в накопителях крутится функционал «сборщика мусора», который занимается тем, что отыскивает «дырявые» блоки, в которых меньше всего актуальных страниц, и переносит актуальные страницы в новый блок. Таким образом «дырявый» блок освобождается полностью от актуальных страниц и его можно стереть… А в новом же блоке все страницы станицы остаются актуальными. Напоминает дефрагментацию.

ca3rqqysdegj56guxvq5iv5mq7a.png

Wear Leveling


Ничто не вечно под луной, а NAND-flash — особенно. Так уж вышло, что NAND-flash память имеет ограниченный ресурс, который выражается ограниченным числом циклов стирания блоков (возрастом блока). Блоки, которые стирались большее число раз (старые блоки), имеют большую вероятность выхода из строя, чем те, которые менее изношенные (молодые блоки).

Задумывались ли вы когда-нибудь над тем, что надо бы таблицу FAT перенести из нулевых адресов накопителя куда-нибудь в другое место, чтобы не протереть дырку в адресном пространстве флешки? Это вряд ли, да и не следует над этим думать. Потому что во флешке работает механизм выравнивания износа блоков. Суть его в том, что молодые блоки, меняются местами со старыми в принудительном порядке, чтобы износ всех блоков был равномерным в течение эксплуатации накопителя. Так у накопителя есть шанс жить долго и счастливо, пока все его блоки не умрут в один день.

e_2kx-dt-4srlldeoiowdv75wpk.png

А теперь о главном — зачем таки «заряжать» флешки?

1) Бывало у вас такое, что вы изо дня в день собираетесь постирать носки, но каждый вечер оказывается не до этого? А потом наступает такой момент, что чистых носков на завтра просто физически не осталось! И тогда вам приходится жертвовать сном ради стирки носков. Еще хуже, если приходится опаздывать на работу с феном в руках.

Примерно это же происходит и с алгоритмом сборки мусора в FTL. Пользователь зачастую использует флешку для переноса каких-то данных с одного компьютера на другой. При этом, сценарий действий следующий: воткнуть флешку в комп — записать быстро файлы — выдернуть флешку — добежать до другого компа — воткнуть флешку — считать файлы. Через некоторое время пользователь начинает замечать, что его накопитель медленно работает. Обычно в таких случаях грешат на то, что «ну, просто флешка дешевая, старая. Вот, куплю новую, она будет летать!». И действительно будет! Но ее, скорее всего, постигнет та же участь через некторое время. Дело в том, что сценарий таких «короткометражек» не позволяет алгоритму garbage collection производить высвобождение блоков для записи, что рано или поздно приведет к тому, что свободных блоков больше просто физически не останется. И тогда контроллер вынужден сначала заняться высвобождением блоков, а затем только записью ваших файлов в них, отсюда и потеря скорости. Чтобы быть готовым принять ваши данные на полной скорости, накопителю необходимо свободное время для того, чтобы «постирать носки» заранее. Как легко догадаться, «зарядка» флешки снимает эту проблему, предоставляя контроллеру достаточно времени для наведения прядка в данных.

34s3dys9vagwbo3n-l52ib-h_ws.jpeg

2) Проблема нехватки «личного времени» контроллера актуальна и для алгоритма выравнивания возрастов. Алгоритм Wear Leveling выполняется контроллером в моменты простоя накопителя, пока нет задач для записи или чтения пользовательских данных. Если же накопитель работает в режиме «короткометражек», то времени на выравнивание износа блоков просто нет. Неравномерный износ блоков приводит к тому, что старые блоки выходят из строя. При этом число доступных для записи блоков уменьшается, пока не наступит критичный момент, когда свободных блоков для записи просто не останется, хотя NAND-flash память в целом еще не изношена, и могла бы еще долго прослужить.

oj6sk3f7dl60b-co866kmnduysq.jpeg

3) Эволюция научила нас прикапывать дорогие нам ценности где-нибудь подальше от проходных мест. Это хорошо работает в случае кладов и необитаемых островов. Но с цифровыми данными и NAND дело обстоит с точностью до наоборот. Наверняка, у вас были случаи, когда вы скинули на флешку какие-то фотографии со свадьбы друга, год флешка полежала в ящике стола (как вам казалось, в целости и сохранности), а потом некоторые из фоток прочитались только наполовину. Дело в том, что единожды записанная в NAND-flash память информация способна «протухнуть» со временем. Производитель памяти не гарантирует 100% сохраняемость данных, а просто озвучивает вероятность возникновения битовых ошибок.

Конечно же, контроллер накопителя решает задачу устранения битовых ошибок, добавляя избыточный код к данным, но какой бы ни был большой этот код, со временем заряд в ячейках NAND-памяти рассасывается, и число битовых ошибок может перевалить за любую корректирующую способность. Нельзя оставлять данные лежать долго в одиночестве в NAND-flash памяти, за ними надо ухаживать. А именно — периодически перезаписывать. Правильный контроллер производит периодически перечитывание данных, контроль числа битовых ошибок и перезапись данных в случае необходимости (пока число битовых ошибок не превысило допустимое). Разумеется, для этого также контроллеру необходимо «свободное время».

Из всего вышесказанного подведу итог: не стесняйтесь «заряжать» флешки, это благоприятно сказывается на их быстродействии и надежности. А если вас захэйтят технари, просто дайте им ссылочку на эту статью.

© Habrahabr.ru