Меню сайта
Категории каталога
loader(8): оптимизация и результаты [2012]
Наконец-то я нашёл время и ресурсы на проведение оптимизации в загрузчике системы. Организовал стенд на базе VMWare ESXi, в которой я создал несколько виртуалок с FreeBSD 10, установленных с использованием различных комбинаций таблиц разделов и файловых систем. Расшарил по NFS рабочий каталог с исходниками системы со своей машины, подключил его к виртуалкам и начал отладку... Ну как "отладку", добавил несколько printf'ов в libstand и в драйвер диска biosdisk; включил отладку в недавно добавленном модуле с DISK API; в виртуалках создал файл /boot.config с опциями "-D -S115200", в VMWare настроил запись вывода с последовательного порта в файл и начал тесты. Получив логи, начал смотреть код и искать способы уменьшения количества дисковых операций, которых оказалось великое множество. В итоге, в модуль с DISK API был добавлен код кеширования обращений к дискам. А нужно сказать, что почти каждое открытие файла с использованием libstand приводит к чтению метаданных таблиц разделов. Чтобы уменьшить это число обращений раньше использовался bcache - блочный кэш. Но, printf'ы внутри дискового драйвера показали, что его эффективность довольно низка, а при использовании GPT - совсем удручает. Итак, новый кэш работает по другому. При открытии файла, запрос open() приводит к вызову функции devopen(), которая и "открывает" текущее устройство (обычно диск, с которого происходит загрузка), например, disk1p3. Открытие диска - это чтение его метаданных, поиск таблиц разделов и определение смещения, с которого начинается открываемый раздел. Каждое успешное открытие добавляет в кеш запись. Таким образом, при открытии следующего файла на этом диске, уже не нужно будет читать метаданные, а смещение будет прочитано из кэша. В результате, если раньше при загрузке с UFS чтение метаданных выполнялось примерно 50 раз (с учётом попаданий в блочный кеш - около 30), то сейчас это происходит 1 раз. Далее меня заинтересовало почему при открытии, например, ядра или его модулей, в логе загрузки эта операция отображается несколько раз (от трёх до четырёх)? Т.е. конечно чтение всего ядра не происходит четыре раза, но каждое открытие сопровождается чтением некоторого объёма данных, и только последнее открытие читает заметно больший объём данных. Как оказалось, для архитектуры x86/x64 loader одновременно поддерживает несколько форматов ELF - 32-битные и 64-битные. Причём в массиве, где перечислены указатели на обработчики этих форматов первыми стоят 32-битные, а затем уже 64-битные. Поэтому loader при загрузке модулей ядра в цикле "пробует" модуль каждым обработчиком, пока не найдёт подходящий. И так как у меня тестовые машины 64-битные, то обработчик ядра стоит 3-им в этом массиве, а обработчик модулей ядра - 4-ым. В общем, эта досадная несправедливость в отношении 64-битных систем была мной ликвидирована тоже. В итоге, я сравнил результаты по затратам времени загрузки с момента старта loader'а и до момента запуска ядра в разных конфигурациях системы: UFS+GPT ZFS+GPT ZFS+GPT+несколько дисков Старый loader 7,203 сек 20,584 сек 26,079 сек Обновлённый loader 4,334 сек 9,422 сек 11,245 сек
Во всех случаях, кроме самого ядра загружалось ещё несколько модулей. Источник: http://bu7cher
Категория: Установка и настройка | Добавил: oleg (14.10.2012) | Автор: bu7cher
Просмотров: 2589 | Рейтинг: 0.0 /0 |
- Оценить -
Отлично
Хорошо
Неплохо
Плохо
Ужасно
Добавлять комментарии могут только зарегистрированные пользователи.
[
Регистрация |
Вход ]
Форма входа
Друзья сайта