Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 128, АВГУСТ 2009 г.

Сапоги-скороходы для тукса. MegaFAQ по разгону Linux на десктопе

Евгений Зобнин (zobnin@gmail.com), Сергей Яремчук (grinder@ua.fm), Денис Колисниченко (dhsilabs@mail.ru)

Прожорливость современных Linux-дистрибутивов легко ощутить, запустив один из них на компе с 512 Мб ОЗУ или купив ASUS EeePC. Нерасторопная загрузка десктопа, борьба приложений за ресурсы, тонущий под собственным весом Firefox и постоянно шуршащий жесткий диск - зрелище пугающее и обескураживающее. Где же тот Linux, который способен работать на машинах с 16 Мб оперативки и процессором семейства i486? А ведь он до сих пор там, внутри, задавленный грузом многочисленных библиотек, бесполезных демонов, жирных приложений и красивостей рабочего стола.

Q. В моем любимом дистрибутиве Linux загружается огромное количество сервисов. Это занимает кучу времени. Можно ли как-то ускорить загрузку?

A. Можно попытаться организовать параллельный запуск сервисов. Найди в файле /etc/init.d/rc такой код:

for i in /etc/rc$runlevel.d/S*
do
case "$runlevel" in

*) startup $i start ;;
esac
done

И замени строку «*) startup $i start ;;» на «*) startup $i start & ;;». Так загрузочные процессы будут запускаться параллельно: последующий сервис начнет стартовать, не дожидаясь выполнения предыдущего. После модификации конфига перезагрузи систему. Если тебе повезет, и Linux запустится корректно, то время его запуска сократится примерно в два раза. Но он может и не загрузиться. У этого способа есть один недостаток. Представим, что нам нужно запустить 4 сервиса: A, B, C и D, причем сервис C – довольно громоздкий, и его запуск занимает, скажем, секунд 15-20, а сервис D – небольшой, но он зависит от C. Получается, что C еще не запущен, а D запущен, но он не может работать без C. В результате, D окажется неработающим. В реальной системе таких сервисов может быть много.

Что же делать? Ответ прост: нужно использовать программу cinit, которая параллельно запускает сервисы, но при этом проверяет зависимости. Таким образом, cinit не запустит сервис D, если сервис C, необходимый для корректной работы D, еще не запущен. Прочитать о правильной настройке cinit можно по адресу: nico.schottelius.org/documentations/speeches/metarheinmain-chaosdays-110b/cinit/view. Еще один вариант - перевести дистрибутив на систему инициализации InitNG (Init Next Generation). За подробностями обращайся к статье «Молниеносная загрузка тукса» (][_03_2006).

К слову, убунтовский upstart, использующий метод параллельного запуска сервисов, грузит дистрибутив до окна логина за ~10 секунд.

Q. А как отключить ненужные сервисы?

A. Отключить сервисы можно с помощью графического конфигуратора (drakxservices в Mandriva, system-config-services в Fedora, services-admin в Ubuntu), но намного проще «прибить» ссылку в соответствующем rcN.d-каталоге (или же переместить ее в другой каталог – на случай, если когда-то понадобится включить сервис).

Q. Как увеличить объем виртуальной памяти?

A. Набери команду free в консоли. Сколько виртуальной памяти (физическая память плюс область подкачки) сейчас свободно? Если все заполнено, например, осталось несколько мегабайт физической памяти и столько же в своп-области, значит, памяти катастрофически не хватает. Лучший совет - это купить еще один модуль оперативки. В качестве временного решения могу предложить создать и активировать дополнительный файл подкачки (в нашем случае его размер – 512 Мб):

# dd if=/dev/zero of=/swap/sw-file bs=1k count=524288
# mkswap /swap/sw-file 524288
# swapon /swap/sw-file

Чтобы последнюю команду не вводить каждый раз при запуске системы, пропиши ее в загрузочных сценариях (желательно после команды «swapon -a»).

Q. Как повысить производительность виртуальной памяти?

A. Если ты работаешь с небольшими программами и часто переключаешься между ними, можно установить коэффициент подкачки равным 20 или 30. В этом случае переключение между приложениями будет мгновенным, но замедлится их работа. Поскольку эти приложения небольшого размера, то это не будет заметно.

Если же на протяжении дня ты в основном работаешь с громоздкими приложениями, например, OpenOffice, или занимаешься обработкой изображений в GIMP, лучше установить значение коэффициента, превышающее 70, например, 80 или даже 85. Тогда переключение между приложениями будет медленное, зато основное приложение будет работать быстро. Изменить значение коэффициента подкачки можно с помощью команды:

# echo "20" > /proc/sys/vm/swappiness

Или через /etc/sysctl.conf:

vm.swappiness = 20

Поэкспериментируй с различными параметрами - только так можно подобрать для себя оптимальное значение. Кроме того, не мешает ограничить размер файлового кэша, чтобы он занимал меньше ОЗУ (так мы предотвращаем свопинг), и активировать принудительный сброс буфера в случае, если приложения суммарно займут более половины памяти:

vm.pagecache = 90
vm.dirty_ratio = 50

Q. Как оптимизировать работу жесткого диска?

A. В большинстве случаев система сама подбирает оптимальные параметры работы с жестким диском. Используя утилиту hdparm, есть возможность дополнительно повысить производительность. Чтобы получить информацию о текущих настройках харда, запустим команды:

$ hdparm /dev/sda
$ hdparm -i /dev/sda

Параметров будет получено много, но на производительность напрямую влияют лишь некоторые из них:

  • MaxMultSect/MultSect - максимальное/текущее число секторов, которые диск может считать за один проход (для максимальной производительности они должны совпадать);
  • PIO modes/DMA modes - режимы, которые поддерживает жесткий диск (режим, помеченный звездочкой, является текущим);
  • multcount - число одновременно считываемых секторов;
  • I/O support - режим работы жесткого диска (16-битный режим, 32-битный режим или 32-битный синхронный режим);
  • using_dma - использовать DMA или нет;
  • readahead - количество секторов для упреждающего чтения.

Переопределить установки для конкретного диска можно в командной строке (вступают в силу немедленно) или – указав их в конфигурационном файле /etc/hdparm.conf или /etc/default/hdparm (потребуется перезагрузка). Влияние изменений можно протестировать при помощи команды «hdparm -tT /dev/sda».

Для примера включим DMA (-d1), 32-битный режим I/O (c1); multicount выкручиваем по максимуму (-m64), а упреждающее чтение ставим равным multicount (-a64). Установка параметра '-u1' разрешает драйверу параллельно обрабатывать несколько прерываний, что повышает производительность:

# hdparm -u1c1d1m64a64 /dev/sda

Дополнительно можно поиграться с параметром '-W' (0/1), отключающим/включающим кэширование. Его значение зависит от производителя и модели харда и по умолчанию не определено.

Q. Как задать отдельной программе приоритет для работы с диском?

A. Аналогично nice, позволяющей изменить приоритет процесса, утилита ionice задает приоритет на использование харда для процесса или приложения. В Ubuntu ionice входит в пакет schedutils. Приоритет указывается при помощи класса и собственно приоритета в виде:

ionice -c класс -n приоритет -p PID

Приоритет - число от 0 до 7 (чем меньше число, тем он выше). В позиции класс три значения:

  1. Real time – планировщик дает преимущество при доступе к диску выбранному процессу, без внимания на работу других процессов (8 уровней приоритета [0-7]);
  2. Best Effort – класс, устанавливаемый по умолчанию для всех процессов (8 уровней приоритета);
  3. Idle - программа получает право на использование жесткого диска только в том случае, если другая программа не требует диск; приоритеты не задаются.

Вместо PID можно указать имя процесса:

$ sudo ionice -c2 -n0 mplayer

Q. Как разогнать файловую систему?

A. Через отключение ненужной функциональности. Любая современная ФС достаточно гибка, но напичкана большим количеством функций, которые лично тебе могут и не понадобиться. Возьмем, к примеру, ext3, наиболее популярную сегодня Linux-ФС. Она обладает двумя важными, но далеко не всегда необходимыми функциями: журналирование и временные метки последнего доступа к файлу. Обе они требуются, но только в случае, если твоя система целиком «сидит» на одном разделе. Если же установить ОС на несколько разделов, каждый из которых будет ответственен за хранение файлов конкретного каталога, – мы получим возможность использовать для них разные файловые системы с различным уровнем функциональности. Смотри:

  • Раздел #1. Корень файловой системы, то есть каталог /.
  • Раздел #2. Каталог /usr, хранящий все устанавливаемое программное обеспечение.
  • Раздел #3. Каталог /home, личные данные пользователей.
  • Раздел #4. Каталог /tmp, временные файлы.
  • Раздел #5. Каталог /var, множество изменяемых во времени данных приложений.

Зачем журналировать и обновлять время последнего обращения к файлам для корня файловой системы, который изменяется очень редко (обычно во время переустановки ядра или обновления дистрибутива)? Ответ: незачем. Монтируем к корню шуструю ext2 (которая не ведет журнал) с опцией noatime (не использовать временные метки последнего доступа). То же относится к каталогу /tmp, за исключением того, что в этом случае atime лучше оставить. Каталог /var хранит множество мелких файлов, для управления которыми отлично подходит ReiserFS, /home - важнейшие данные пользователя, поэтому к нему лучше подключить журналируемую ФС.

Кстати, для ускорения доступа к каталогу /tmp можно использовать файловую систему tmpfs, хранящую все свои файлы в оперативной памяти. Это отличное подспорье тогда, когда памяти много, а девать ее некуда. Вот строка для /etc/fstab:

tmpfs /tmp tmpfs size=512m,mode=1777 0 0

Можно пойти и радикальным путем: не разбивать диск на множество разделов, а просто перейти на файловую систему ext4. В июльском номере журнала, в статье «На пути к совершенству», мы много говорили о ней и показали бенчмарки, которые доказывают, что производительность ext4 за последнее время возросла настолько, что другие ФС на ее фоне выглядят поделками второкурсников.

Q. Что можно сделать с видеоподсистемой?

A. Первое - отказаться от использования стандартных видеодрайверов, поставляемых в комплекте с X.org. Особенно ущербны драйвера для карточек ATI и nVidia, и если первые способны хотя бы на что-то в плане 2D-ускорения (во многом благодаря открытию некоторых спецификаций), то вторые - просто ужасны. Я на собственной шкуре ощутил примитивизм драйвера nv, когда попытался поиграться с KDE 4.1.1. По уровню тормознутости картинка легко обставляла UT, запущенный на 166'ом пентиуме (тоже личный опыт), и это несмотря на 1 Гб оперативки, 2.6-гигагерцовый камень и полностью отключенные эффекты. После установки официальных дров кеды полетели быстрее XFCE. Ответ на вопрос «почему?» легко найти, прочитав документацию к nv, которая прямо говорит о полном отсутствии функций 2D-ускорения (именно 2D) в драйвере.
Второе, что можно сделать - установить простую утилиту nvclock (www.linuxhardware.org/nvclock), которая позволит разогнать видеокарту как по частоте видеочипа, так и по памяти. На моем домашнем компе установлена старенькая видеокарта nVidia 5900FX. Когда-то давно я запускал на ней первый Far Cry (через wine). Поначалу он притормаживал даже на средних настройках графики, но после выполнения команды «nvclock -f -n 540», которая увеличила частоту чипа с дефолтовых 400 МГц до 540, игрушка начала без проблем бегать на высоких настройках.

Третье - отключить 3D-эффекты рабочего стола. Операция, которая не несет особого прироста производительности (эффекты не грузят проц, а для 3D-ускорителя это просто семечки), может повысить скорость реакции системы за счет снижения времени на исполнение дополнительного кода и количества переключений контекста.

Q. Как отключить Compiz?

A. Все зависит от твоего дистрибутива. Например, в Ubuntu нужно выполнить команду «Система -> Параметры -> Внешний вид» и на вкладке «Внешний вид» отключить эффекты рабочего стола. В других дистрибутивах можно использовать универсальные команды:

# gtk-window-decorator --replace (если у тебя GNOME)
# kde-window-decorator --replace (если у тебя KDE)

Q. Можно ли как-то использовать ресурсы видеоадаптера во время его простоя?

A. Да, можно. ATI и nVidia, два основных игрока на рынке видеоадаптеров, не так давно выпустили специальные фреймворки, позволяющие перенести некоторые прожорливые вычислительные задачи на GPU. Позднее была сформирована специальная группа Khronos Group, разработавшая стандарт OpenCL (www.khronos.org/opencl), который описывает стандартизованный интерфейс доступа к GPU для вычислительных задач. Беда в том, что пока почти не существует приложений, использующих эту технологию. А вот задействовать установленную на видеоадаптер высокоскоростную память удастся прямо сейчас. Ядро Linux включает в себя специальный драйвер Memory Technology Device (MTD), который позволяет адресовать не только оперативную память, но и память любого устройства, подключенного через шину PCI. Методика, описанная в статье en.gentoo-wiki.com/wiki/TIP_Use_memory_on_video_card_as_swap, использует этот драйвер для создания (псевдо)блочного устройства, которое будет использовать видеопамять в качестве хранилища данных. На устройстве можно создать своп или файловую систему для хранения файлов, например, каталога /tmp. Интересная особенность: подход отнюдь не отменяет возможности использования графических приложений, позволяя зарезервировать небольшой кусочек памяти для VGA-режима.

Q. Интернет-соединение тормозит, периодически появляются раздражающие задержки. Как исправить?

A. Это известная проблема в некоторых дистрибутивах Linux с включенной по умолчанию поддержкой IPv6. Если поддержка новой версии протокола IP в системе не нужна, ее очень просто отключить. Для этого достаточно закомментировать строку, содержащую «ipv6», в конфиге /etc/modprobe.conf, или занести этот модуль в блэклист, добавив в файл /etc/modprobe.d/blacklist.local запись «blacklist ipv6».

Если проблема не решена, следует включить/отключить параметр TCP window scaling, определяющий масштабирование TCP-окна, то есть установку количества пакетов, которое может быть послано без подтверждений. Временно отключить его можно командой:

# sysctl -w net.ipv4.tcp_window_scaling=0

Если это поможет, заносим следующую строчку в /etc/sysctl.conf:

net.ipv4.tcp_window_scaling=0

Другой вариант – не отключать «TCP window scaling», а попробовать подобрать оптимальные параметры для TCP-буфера чтения и записи:

net.ipv4.tcp_rmem = 4096 87380 174760
net.ipv4.tcp_wmem = 4096 87380 174760

Аналогичный параметр есть и для UDP:

net.ipv4.udp_rmem_min = 16384
net.ipv4.udp_wmem_min = 16384
net.ipv4.udp_mem = 8388608 12582912 16777216

Ядро Linux 2.6 включает алгоритмы автоматической оптимизации буферов принимающей и отправляющей сторон, которыми управляют еще три параметра:

net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.netdev_max_backlog = 2500

Вообще, список всех доступных параметров можно получить при помощи такой конструкции: «sysctl -a | grep tcp». В быстрых сетях имеет смысл поэкспериментировать с размером очереди интерфейса. За ее установку отвечает параметр txqueuelen команды ifconfig:

# ifconfig eth0 txqueuelen 1000

Начиная с ядра 2.6.7, появились альтернативные традиционному «reno» алгоритмы обработки перегрузки (потери пакета в канале). Получить полный их список можно, введя:

# sysctl net.ipv4.tcp_available_congestion_control

В зависимости от дистрибутива и версии ядра, в ответ получим разный список. Последние релизы могут содержать 6 возможных вариантов: reno, cubic, bic, htcp, vegas и westwood. В первую очередь, рекомендую попробовать cubic или htcp, – они считаются наиболее эффективными. Для перегруженных сетей, в которых теряется большое количество пакетов, попробуй westwood.
Задается алгоритм просто:

sysctl -w net.ipv4.tcp_congestion_control=htcp

Q. Как отключить ежечасные и ежедневные задачи?

A. Почти во всех дистрибутивах присутствуют четыре специальные задачи демона cron, которые поочередно запускают все скрипты, расположенные в каталогах /etc/cron.hourly (ежечасно), /etc/cron.daily (ежедневно), /etc/cron.weekly (еженедельно) и /etc/cron.monthly (ежемесячно). Обычно они не создают особой нагрузки на систему, но иногда в первый из этих каталогов попадают прожорливые скрипты, которые будут притормаживать систему каждый час. Для решения проблемы достаточно подчистить каталог /etc/cron.hourly (имена скриптов обычно весьма многословны).

Q. Можно ли сжать модули ядра для экономии места?

A. Да, конечно! Для этого можно использовать сценарий mcompress, приведенный ниже:

#!/bin/sh
VER=`uname -r`
MAJ=`uname -r | awk -F. '{print $1}'`
MIN=`uname -r | awk -F. '{print $2}'`
if [ $MAJ -ge 2 -a $MIN -ge 5 ]; then
OBJ=ko
else
OBJ=o
fi
find /lib/modules/`uname -r`/ -name *.$OBJ -exec gzip -9 '{}' ';'
depmod -a; depmod -A

Q. Как освободить дополнительное место на диске?

A. Основной метод экономии места – это удаление ненужных пакетов. К примеру:

  • xsane, sane-utils, libsane, foomatic-db-hpijs, hpijs, hplip – поддержка сканеров и некоторых МФУ от HP (если у тебя нет сканера или принтера HP, или даже если есть только принтер, но нет сканера, то можно удалить первые три пакета);
  • w3m – текстовый браузер (когда ты в последний раз им пользовался, не помнишь? Вот и я тоже);
  • bogofilter, bogofilter-{bdb,common} – спам-фильтр;
  • splix - драйвер для принтера Samsung SPL2 (у меня Lexmark, мне драйвер от SPL2 не нужен);
  • gucharmap - таблица символов;
  • onboard - экранная клавиатура;
  • rss-glx - набор скринсейверов.

Этот список можно продолжать очень долго. Затем нужно пройтись по шрифтам. По умолчанию установлено огромное количество фонтов, которые занимают достаточно места и при этом практически никогда не используются. Например, пакеты шрифтов ttf-arabeyes, ttf-lao, ttf-arphic-uming, ttf-sazamani*, ttf-indic*, ttf-unfonts-core, ttf-thai* можно смело удалять. После этой операции моя система полегчала примерно на 80 Мб.

Особого внимания заслуживают пакеты с документацией. Обычно их нельзя удалить без удаления основного пакета. Но документация нужна далеко не всегда. Часто ты читал документацию по тому же OpenOffice или GIMP? Тем более, бывает, что для одного и того же продукта установлено два пакета с документацией – на русском и английском. Удалить хотя бы один пакет нельзя, иначе будет в лучшем случае удален и второй, в худшем – весь продукт. Кроме того, все пакеты справки содержат файлы вроде README, CHANGES, GPL, LICENSE, AUTHORS, ChangeLog и т.д. В итоге, у тебя на винте скапливается огромное количество копий этих файлов! Сэкономить место довольно просто. Заходи в /usr/share/doc и удаляй все, что видишь. Не беспокойся, даже если тебе понадобится документация для какого-то пакета, достаточно переустановить либо сам пакет, либо пакет с документацией. В моей системе документация занимала 250 Мб.

Q. Существуют ли более хардкорные методы оптимизации?

A. Да, но мы не рекомендуем применять их на практике. Метод гентушников. Старый добрый способ оптимизации через сборку всего и вся с привязкой к конкретному семейству процессоров и задействованием жестких флагов оптимизации. Поэтому, если ты замыслил получить прирост производительности в 3-5%, устанавливай Gentoo со Stage1 и запоминай следующую комбинацию флагов оптимизации:

  • O2 - задействовать все «легальные» методы оптимизации.
  • fomit-frame-pointer - не сохранять указатель на кадр стека.
  • funroll-loops - разворачивать циклы.
  • mcpu=семейство_процессоров - подгон результирующего кода под конкретный процессор.
  • march=семейство_процессоров - предыдущая опция + использование инструкций этого семейства процессоров.
  • pipe - не использовать временные файлы (ускоряет компиляцию).

Возможные значения опций '-mcpu' и '-march' смотри здесь: gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html.

Метод ниндзя. Удаляем все оконные среды и менеджеры окон, избавляемся от totem, amarok, k3b, firefox, thunderbird и прочих особо жадных до ресурсов приложений. Ставим табовый менеджер окон wmii, ion3 или awesome, mc в качестве навигатора, links2, dillo или текстовый elinks для навигации по web, mutt для чтения почты, snownews для RSS, sonata + mpd для музыки, mplayer для видео. После этого запасаемся едой и закрываемся на три дня в комнате, в течение которых проникаемся дзен и настраиваем все это хозяйство. Через две недели становимся свободными от мышки и весьма продуктивными людьми.

Метод отцов. Включает в себя все процедуры предыдущего пункта с постепенным переходом на консольные приложения, последующим погружением в консоль и познанием сущности screen/tmux.

Планировщики ввода/вывода и процессов, реалтайм ядра

Ядро Linux поддерживает несколько различных алгоритмов планировщиков ввода/вывода (I/O scheduler) и процессов. Список I/O scheduler можно получить, прочитав файл /sys/block/sda/queue/scheduler:

# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

Алгоритм CFQ (Completely Fair Queuing), используемый по умолчанию в современных ядрах, идеально подходит для случаев, когда множество программ могут потребовать доступ к диску, а также для многопроцессорных систем, которым требуется сбалансированная работа I/O подсистемы с различными устройствами. При больших операциях считывания его можно переключить на Deadline или Anticipatory:

# echo anticipatory > /sys/block/sda/queue/scheduler

Аналогична ситуация и с планировщиком процессов: здесь можно выбирать между старичком O(1), CFS (Completely Fair Scheduler, абсолютно справедливый планировщик, включен в 2.6.23) или другими планировщиками, но, правда, для этого придется пересобирать ядро.
Подробнее о планировщиках читай в статье «Позови пингвина на планерку», опубликованной в ][_12_2007.

Содержание
ttfb: 9.4919204711914 ms