Итак. Поговорим немного о трансляции адресов. В некотором смысле доступ к логическому блоку на SSD отличается от доступа к такому же блоку на HDD. И это различие принципиально неустранимо.
Позвольте мне для начала привести понятную аналогию. Допустим, у Вас есть камера хранения. Все ячейки в ней пронумерованы и собраны в шкафчики с прямоугольной сеткой отделений.
Тогда, чтобы найти ячейку с нужным номером, Вам не придется просматривать их все - Вы элементарно сможете подсчитать, что она "третья слева в пятом сверху ряду второго шкафчика".
Понятно, что это привычный всем нам метод адресации, который абсолютно одинаково работает и в жестких дисках, и в микросхемах ОЗУ.
Примечание: понятно, что приведенное выше высказывание не является абсолютно точным. Пользователь имеет доступ не к физическим, а к логическим блокам жесткого диска и контроллер диска хранит в служебных областях (на "отрицательных цилиндрах") некоторый достаточно простой и совершенно статический, если не считать списка переназначенных в процессе работы секторов (G-листа), транслятор. Точно так же, любой процесс имеет доступ не к физическим, а к логическим адресам памяти. Теоретически, конечно, это не обязательно - страничную организацию памяти можно и отключить, но на практике все операционные системы всегда её используют. Кроме совсем уж древних, таких как MS-DOS или Xenix. Обе от Microsoft. Да, и конечно код исполняющийся в SMM-режиме тоже игнорирует страничную адресацию. Но его ведь нельзя назвать процессом, верно?
Резюме: если пытаешься рассказать о чем-то не приблизительно, а с максимальной точностью, рассказ неизбежно обрастает кучей ненужных подробностей, становится длинным, нудным и вообще никому не интересным.
Поэтому, я надеюсь, меня простят, если в дальнейшем я буду опускать некоторые подробности и не отвлекаться на специальные случаи.
Теперь рассмотрим хранение информации на твердотельном накопителе. Чтобы избежать преждевременного износа поверхности, мы не можем установить статическое соответствие между номерами физических ячеек и логических блоков.
Значит, в каждой ячейке нам придется хранить не только само содержимое логического блока, но и его номер.
Номер блока, таким образом из механизма прямой адресации превращается в метаданные (данные о данных), которые сами по себе надо разыскивать.
Как это организовать в камере хранения? Самый простой способ - прикреплять к каждой ячейке ярлык, на котором записан этот самый логический номер блока и потом искать его во всех ячейках, пока не найдешь. Или не найдешь.
Понятно, что при этом надо было бы при любой операции доступа к диску читать весь диск от начала и до конца.
Производительность была бы ужасающе низкой и едва ли пользователей соблазнила бы перспектива покупать диски, каждое чтение/запись которых занимает 1-2 минуты.
Вариант с прямым отображением (каждому логическому блоку соответствует физический блок с тем же номером) мы уже отвергли как непригодный с точки зрения износа. Хотя износ - не единственная причина. Представьте себе, что Вы решили изменить содержимое одного какого-то блока.
Как это происходит в HDD? Самым естественным образом - мы его читаем, редактируем, записываем обратно. Как это будет выглядеть на SSD с прямым отображением? Мы читаем страницу, редактируем... И тут выходит осечка - чтобы повторно выполнить запись уже записанной ранее страницы, надо сначала её стереть. Причем не только её, а все 512к физического блока, который состоит из 128 страниц.
Но в этом блоке, скорее всего, занято больше, чем одна страница. Поэтому мы должны сначала прочитать все занятые страницы (до 128 операций чтения), стереть блок и записать страницы обратно (до 128 операций записи).
Поверьте мне на слово - это будет
очень долго. К тому же, каждая запись будет вести к износу NAND. Один раз перезаписали эти 512к - выполнили 1024 операции стирания (если писали по одному 512-байтовому блоку). Три-пять перезаписей - и блок труп.
Итак, прямое отображение не годится. Конечно, можно немного улучшить ситуацию, используя очередь комнд (NCQ), чтобы писать не по одному блоку, а по несколько, но, сами понимаете, принципиально положения это не улучшит.
Что тогда делать? Можно одним махом решить все проблемы - хранить где-нибудь таблицу соответствия логических блоков физическим! Тогда любой логический блок можно будет записать на абсолютно любое место, что разом решает почти все проблемы. Конечно, хранить такую таблицу можно только в очень быстродействующем запоминающем устройстве, которое, к тому же, не имеет ограничений по числу записи. Но у нас уже давно есть такое устройство! Это обычная DRAM. Поставим микросхемку памяти на диск - всё равно контроллеру нужна своя RAM для работы.
И понадобится этой памяти не так уж много. Давайте посмотрим - диск у нас, ёмкостью, допустим, 128ГБ, мы хотим хранить данные о каждом 512-тибайтном логическом диске. Адрес блока 32-битовый, то есть нам надо всего 4 байта RAM на каждый блок. 4/512 = 1/128. Меньше одного процента от ёмкости диска. Значит на 128 ГБ-ный диск нам потребуется... потребуется... ЦЕЛЫЙ ГИГАБАЙТ ПАМЯТИ?!! Только для хранения L2P таблицы?!! (L2P - "logical to physical". Таблица трансляции адресов блоков. Составная часть FTL.)
Нереально. Это будет стоить слишком дорого. К тому же, приведет к резкому увеличению энергопотребления диском.
Можно, конечно, установить соответствие не между логическим блоками, а между 4096-байтными страницами. Требуемый размер RAM уменьшится в 8 раз, но всё равно останется запредельно большим.
Итак, полностью ассоциативное отображение - тоже не вариант.
Что делать? Как решить эту новую, возникшую только с появлением SSD проблему? Постойте... А настолько ли она новая?
Вспоминается мне, что я уже читал о чем-то подобном. В частности, в статьях про устройство процессора. Вспомнил!
Это же кэш-память! Она устроена абсолютно так же. Только в процессоре количество кэш-памяти меньше размера ОЗУ, а в SSD количество логических блоков равно количеству физических.
Лезем в интернет за инфомации об устройстве кэш-памяти и выуживаем оттуда не очень понятное, зато очень весомо звучащее словосочетание "частично-ассоциативный кэш". И решение сразу становится очевидным. Будем хранить в памяти не таблицу соответствия 512-байтовых логических блоков, и даже не 4096-байтовых страниц, а 512-кбайтных физических блоков. Той самой минимальной единицы для операции erase.
Сколько в этом случае потребуется RAM для хранения L2P таблицы? 4 байта RAM на 512к объема диска... Получается 1 мегабайт. Это легко можно себе позволить. Можно позволить даже больше. Итак, останавливаемся на поблочном отображении? К сожалению, тоже нет. Мы сейчас рассматриваем уже третий вариант установить отображение логических блоков на физические и ни один из них не применяется ни в одном из известных мне SSD.
Прямое отображение, полностью ассоциативный кэш, частично ассоциативный кэш - ни один из этих вариантов не подходит. Кстати, почему производителям не подошел так удачно придуманный нами вариант с частично ассоциативным кэшем? Причины старые - износ и скорость доступа. В полностью ассоциативном кэше мы можем тупо записывать страницу с одним и тем же номером (то есть один и тот же логический блок) снова и снова, но каждый раз контроллер SSD будет производить запись на новое место. Все ячейки (точнее 512-кбайтные блоки) будут изнашиваться одинаково и количество операций записи в каждую ячейку будет одинаковым.
В частичном ассоциативном кэше контроллер тоже каждый раз будет производить запись в новую страницу. Вот только если в предыдущем случае это могла быть любая страница и в 512-ти кбайтный блок происходило 128 записей до его заполнения и перехода к следующему блоку, в частично-ассоциативном в каждом блоке есть только одна страница пригодная для записи логического блока с данным адресом. Поэтому каждая последующая запись будет происходить в новый 512-ти кбайтный блок и, когда свободные блоки закончатся, на каждую операцию записи будет приходиться одна операция стирания. В то время как в полностью ассоциативном кэше 1 операция стирания приходилась на 128 операций записи. Результат понятен - износ больше, скорость меньше. Не совсем то, чего мы хотели, правда?
Вот если бы удалось как-нибудь совместить... Если бы износ был такой же маленький как в полностью ассоциативном кэше, а L2P таблица такая же крохотная как в кэше с посекторной ассоциативностью (сейчас я использовал термин "сектор" вместо "512-ти килобайтный блок". Просто, чтобы хоть немного запутать читателя, которого не удалось заставить бросить чтение раньше). В общем, хорошо бы придумать что-нибудь такое эдакое, чтобы всем было хорошо.
Глупо звучит, правда? Но на практике, именно такие гибридные алгоритмы, которые сочетают в себе черты полностью ассоциативного кэша и частично ассоциативного кэша, действительно были созданы и именно они-то и используются на практике во всех известных мне SSD.
Резюме для тех, кто нашел в себе силы дочитать до конца (надеюсь, таких не найдется): в этом ужасно длинном сообщении очень много букв, но нет ответа ни на один из поставленных ранее вопросов. Что такое внутриблоковая фрагментация? Чем она вредна и почему против неё бессильна программа defrag? Как накопитель вообще отличает свободные страницы от занятых? Что он делает, когда свободных страниц не остается? И при чем тут вообще Windows XP? (при чем-то она должна быть, раз все сходятся на том, что SSD с этой ОС работает плохо).
Ждите ответа в следующей серии. Если меня раньше не забанят за флуд в прикрепленной ветке.
