Ветеран
Сообщения: 2029
Благодарности: 704
|
Профиль
|
Отправить PM
| Цитировать
Итак, пока меня вроде не пытаются остановить, так что продолжу излагать внутреннее устройство SSD на уровне микропрограмм контроллера.
Для начала хочу честно всем сказать, что предыдущее сообщение можно вообще не читать. Оно целиком и полностью было посвящено единственному вопросу: почему из всех возможных схем трансляции адресов наибольшее распространение получили именно гибридные схемы (если не забуду, потом еще расскажу про DFTL. Для общего развития).
Еще одна веская причина не читать предыдущее сообщение состоит в том, что после публикации я его прочитал и ужаснулся количеству орфографических ошибок, пропущенных знаков препинания и откровенно плохой стилистике.
Конечно, если бы я его предварительно вычитал, такого бы наверное не было, но чукча не читатель!
Итак, вернемся в гибридной схеме FTL. В чем она заключается? В том, что для трансляции адресов применяются не одна, а две таблицы. Первая из них транслирует адреса с дискретностью равной размеру блока (принимаем равной 512кБ, хотя встречал и 256к, и 1024к). А с помощью второй реализуется тот самый полностью ассоциативный кэш, который отличается наибольшей производительностью и наилучшим контролем износа (wear-leveling), но требует слишком много оперативной памяти. Поэтому, поступим так, как всю жизнь делали разработчики кэш-памяти - сделаем эту таблицу достаточно маленькой. В результате мы получим, что подавляюще бОльшая часть диска должна состоять из нефрагментированных 512-ти килобайтных блоков (их еще называют блоками данных - data-blocks), но некоторые блоки могут иметь прямое постраничное (4096 или, редко, 8192 байта) отображение и порядок следования логических блоков в этих секторах не имеет значения. Их называют журнальными блоками (log-blocks).
Позволю себе напомнить, что основным достижнием разработчиков SSD является созданная ими терминологическая путаница. Так, слово "блок", о чем мы уже говорили, может значить как логический 512-тибайтный блок, используемый в общеизвестной схеме адресации LBA, так и физический 512-ти килобайтный блок на SSD. Чтобы избежать чересчур частого повторения слова "блок" в разных контекстах, я буду периодически называть 512-ти килобайтный блок "сектором".
Итак, что нам дает наличие двухуровневой схемы трансляции?
Представьте себе, что Вы только что приобрели новенький SSD-диск. Первое, что Вы делаете, это создаете на нем таблицу разделов. Разделов MS-DOS, разумеется. Не GPT же на нем создавать?
То есть записываете MBR. Что происходит на SSD? Контроллер записывает в начало любого свободного блока на диске одну страницу (4096 байт) в которой реально заняты только 512, а остальные 7/8 объема пустуют. В таблице L2P создается запись, которая сообщает контроллеру, что данный сектор является блоком данных (размером 512к) и что в нем хранятся логические сектора с номерами от 0 до 1023. Одновременно модифицируется еще одна служебная таблица в которой записанная страница отмечается как занятая.
Кроме собственно данных в эту страницу записывается также служебная информация. Что это за информация? Номера логических блоков, которые хранятся в этой странице, флаг "занято" отмечающий тот факт, что страница хранит данные и еще один флаг, который используется для определения того, насколько часто данный логический блок перезаписывается системой. В англоязычной литературе логический блок содержащий часто изменяемые данные называется горячей ("hot"), а редко модифицируемые - холодной ("cold").
Вы можете спросить, зачем это вообще нужно? Ведь каждый сектор имеет свой собственный счетчик числа выполненных операций стирания (erase). А иногда даже два счетчика - общий счетчик числа стираний и счетчик недавних стираний.
И что по числу стираний легко понять насколько часто изменяются данные в странице. Что на это можно ответить?
Верно, данные по состоянию носителя страницы мы всегда легко можем получить. Но логический блок не хранится постоянно в одной и той же странице. После каждой модификации он записывается на новое место. А зачастую записывается на новое место и безо всякой модификации. Если контроллер знает, что блок содержит редко изменяемые данные, он запихнет его в более изношенный сектор. Если данные меняются часто - подберет для него сектор получше.
Итак, мы с Вами создали на 128 гигабайтном SSD раздел. Естественно, отвели для него всё имеющееся на диске место.
Полюбовались плодами своих трудов. Подумали. Заглянули в интернет. Прочитали там, что когда SSD остается мало свободного места, его производительность начинает резко падать. Точнее, падать она начинает когда на диске остается процентов 40 свободного пространства, а после того как осталось 10% падение может принять ужасающие масштабы.
Именно о причинах этого падения мы с вами сейчас и говорим.
Падение скорости записи всегда проявляется гораздо более существенно, чем падение скорости чтения.
Сразу оговорюсь: я охотно верю, что среди читателей данного сообщения (если они вообще будут) найдется немало людей, которые гордо скажут "брехня", гордо покажут снимок экрана дефрагментатора, который отметит, что файловая система фрагментирована на 50% и заявят, что никакого снижения производительности они не замечали и никогда не заметят. Отвечу заранее - такие люди говорят о фрагментации на уровне логических блоков. А мы говорим о физических. Это разные вещи.
Обычно мы ожидаем, что компьютер в точности делает то, что мы от него требуем и ничего сверх этого. Дали команду записать блок - он выполняет одну команду записи. Для SSD, к сожалению, это не так. Одна команда записи логического блока, может вылиться в пару сотен команд записи-чтения. Естественно, такие случаи редки и FTL делает всё для того их было как можно меньше. Тем не менее, в среднем на одну команду записи выданную контроллеру приходится большее количество команд, которые он выполняет. Отношение числа выполненных команд к числу выданных называетcя "усилением записи" (write amplification). Чем больше этот показатель - тем меньше производительность SSD.
Рост "усиления записи" внешне проявляется как деградация производительности.
Итак, взвесив все "за и "против", мы решили пожертвовать объемом ради того, чтобы производительность не снижалась по мере заполнения диска. Для этого мы уменьшаем только что созданный раздел со 128 до 100 ГБ. Оставить примерно 20% объема диска не распределенным - хороший способ застраховать себя от проблем, которые могут возникнуть по ходу эксплуатации. Правда это мало кто делает. Диски дорогие, объемы маленькие и жертвовать пятой частью диска просто ужас как жалко!
Тем не менее, мы это сделали. Внесли изменения в таблицу разделов и записали новую версию MBR на диск.
Что происходит на SSD? Диск отмечает страницу с первоначальной версией MBR как "удалённую", записывает в следующую за ней страницу измененный нами вариант, меняет статус этой страницы со "свободно" на "занято" и создает в l2p-таблице страничного уровня запись о том, что нулевой логический блок отображается в первую страницу такого-то сектора. То есть, раньше он отображался в нулевую страницу, а теперь отображается в первую. То есть, сектор фрагментирован и теперь из "блока данных" превращается в "журнальный блок".
На самом деле, конечно, я сейчас описываю только один из возможных вариантов. Каждый производитель использует собственный алгоритм, детали которого обычно не раскрываются. Контроллеры SandForce производят сжатие данных перед записью их в NAND и, тем самым, могут иметь write amplification меньше единицы, что невозможно при других условиях. А Intel X25-M с целью повышения производительности использует закрытый (proprietary) протокол "объединения записи" (write combining) при котором данные сначала накапливаются в буфере, а затем записываются так, чтобы по возможности производить запись сектора целиком.
Это очень хороший алгоритм, он позволяет на новых дисках показать приличный прирост скорости записи. И если диск используется не слишком интенсивно, пользователь скорее всего даже не заметит небольшого недостатка данного алгоритма. Недостаток состоит в том, что объединение в одном секторе данных из разных файлов при интенсивной работе ведет к резкому (более, чем в два раза) снижению производительности. Диск может "задумываться" на какое-то время и не реагировать на команды, пока не разгребет и не переместит фрагментированные секторы.
Однако, еще раз подчеркиваю, что этот эффект замечают только те пользователи, которые интенсивно используют дисковую подсистему. В домашних условиях диск будет бОльшую часть времени простаивать или работать на чтение, поэтому краткие периоды активности, во время которых контроллер будет приводить в порядок свои данные, скорее всего останутся незамеченными.
Сейчас сожру чего-нибудь и продолжу.
А может это на фиг никому не надо? Те, кто интересуется SSD и без меня это всё знают, а тем, которые покупают по принципу "мне вон тот зелененький, он мне по цвету к корпусу подходит", технические детали даром не нужны.
|