Лечим скорость чтения Samsung SSD 840 EVO в Linux

Автор: Дмитрий Канн Чтение на 3 мин
Этот пост  на английском

Некоторое время назад я рассказывал об установке SSD-накопителя серии Samsung 840 EVO вместо штатного в iMac, а также о настройке Linux для эффективной работы с таким накопителем. Сразу же после замены можно наслаждаться исключительной отзывчивостью системы и мгновенным запуском программ. И всё это по цене, наконец-то ставшей относительно доступной.

Samsung 840 EVO.
Samsung 840 EVO.

Но, как водится, счастье долгим не бывает, и осенью 2014 года в прессе много писали (статья на Extremetech, пост на Гиктаймс) о технологическом дефекте, проявлявшемся в постепенном снижении скорости чтения файлов, записанных какое-то время назад. Проблема вызывается «уплыванием» напряжений, выдаваемых ячейками памяти, за пределы нормы, что заставляет контроллер накопителя осуществлять многократные попытки чтения, а это, в свою очередь, выливается в значительное снижение скорости чтения. Причём, чем больше времени прошло с момента записи файла, тем сильнее «уплывают» рабочие уровни ячеек и тем ниже становится скорость чтения этого файла.

По моим измерениям, за 10 месяцев (диск я заменил в августе прошлого года) скорость упала с 280 МБ/с до примерно 30 МБ/с, то есть на целый порядок! «Непорядок», — подумал я.

Ну а что же Самсунг? Компания сначала активно отрицала наличие проблемы, но потом сдалась и выпустила несколько обновлений для её решения. Однако, как выяснилось чуть позже, ни одно из них не устраняло проблему окончательно. В итоге они представили версию драйвера, периодически просто перезаписывающего данные на диске, и успокоились. Загвоздка в том, что драйвер доступен лишь для Windows и Mac OS, а о Linux, как обычно, забыли.

Меня десятикратное падение скорости чтения как-то не радовало, и решение созрело довольно быстро. Нужна утилита, способная перезаписывать файл прямо на диске, теми же самыми данными. Тогда её можно будет периодически, раз в пару месяцев, напускать на раздел с Линуксом (в Линуксе раздел — это ведь тоже файл).

Программа rewrite-inplace

Итак, имею честь представить эту бесхитростную программу: rewrite-inplace. Написана она на простом сермяжном C, и компилируется командой:

gcc rewrite-inplace.c -o rewrite-inplace

Что создаст исполняемый файл rewrite-inplace в текущем каталоге. Программа принимает имя файла в качестве аргумента командной строки. В процессе работы она периодически выводит счётчик перезаписанных байт; её можно также безопасно прервать нажатием Ctrl+C (поскольку данные никуда не перемещаются, сделать это можно в любой момент).

Программа использует низкоуровневые функции ввода/вывода, без буферизации, которая в данном случае скорее вредна, чем полезна.

Инструкция

В целом рекомендуемый мной процесс восстановления скорости чтения таков:

  1. Самое важное: создать резервные копии всего, располагающегося на обрабатываемых разделах и имеющего какую-либо ценность.

    Я не принимаю никаких претензий по поводу смерти вашего любимого файла/диска/кота в результате использования данной программы.

  2. Загрузиться с какого-нибудь live-дистрибутива Linux (например, Ubuntu). Важно: я использовал программу лишь с 64-битной версией системы, не поручусь за работоспособность на 32-битной.

  3. Отключить скринсейвер, блокировку экрана, остановку дисков по времени и т.п.

  4. Скомпилировать программу на запущенной системе (её библиотеки могут отличаться от библиотек основной ОС):
    gcc rewrite-inplace.c -o rewrite-inplace

  5. Запустить GParted, чтобы выяснить имена разделов обрабатываемого диска. Крайне важно: разделы должны быть отмонтированными, проверить можно по их отсутствию в выводе команды mount.

  6. Запустить программу для каждого обрабатываемого раздела из-под root, например:
    sudo rewrite-inplace /dev/sda1 # Это просто пример!

  7. Ждать завершения работы программы и молиться. По окончании проверить целостность раздела командой:
    sudo fsck -f /dev/sda<раздел>

Мои результаты

На перезапись 900-гигабайтного раздела с ext4 программа затратила около трёх с половиной часов; по счётчику байтов было хорошо заметно, что к концу процесс стал значительно быстрее (логично, что самые старые файлы располагаются в начале).

Итог: скорость чтения полностью восстановилась:

$ dd if=/very/old/file of=/dev/null bs=10M
97+1 records in
97+1 records out
1020327050 bytes (1.0 GB) copied, 3.62436 s, 282 MB/s

$ dd if=/another/old/file of=/dev/null bs=10M
95+1 records in
95+1 records out
1000000000 bytes (1.0 GB) copied, 3.56764 s, 280 MB/s

$ dd if=/new/file of=/dev/null bs=10M
1528+1 records in
1528+1 records out
16028794368 bytes (16 GB) copied, 56.9275 s, 282 MB/s

Дисклеймер

Автор не даёт никаких гарантий, вы используете программу НА СВОЙ СТРАХ И РИСК! ■

Подписаться на обновления блога:

Комментарии

Поделиться: