| RSS



Меню

Bookmark and Share


Статистика
Ваш IP: 3.17.150.89
Вы используете: v





Сейчас на сайте:

Тех поддержка ->

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 PHP Эксплоит Windows Server 2008 qip Virtual chroot kernel proc sysctl tune FreeBSD bridge Boot Disk Bluetooth GEO game directx Emulator Python Shell DDoS червь Conficker вирус троян Лаборатория Касперского пиратство apple iPhone ИТ-отрасль Щеголев Microsoft экономический кризис Twitter социальная сеть анонимность Лицензия Open Source ASP.NET MVC уязвимость MySQL база данных файлообмен закон франция пират Skype мобильный Deutsche Telekom Хакер киберпреступник Trend Micro кибератака Германия робот утечка данных персональные данные ноутбук интернет Китай цензура ядро Linux Торвальдс Windows Vista Acer Linux патент браузер Firefox Internet Explorer Opera Net Applications Safari Intel Linux Foundation Moblin Oracle патч банкомат кардер HSM IBM X-Force Cofee сша кибервойна Эстония Dell ИТ-специалист хакерские атаки Pirate Bay контроль кибербезопасность язык программирования The Pirate Bay Пиратская партия утечка информации приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 Баллмер взлом Пентагон ботнет Украина Facebook Cisco cloud Windows XP нетбук торрент музыка биометрический nokia ФБР IP-адрес CIPAV Comcast sms RSA java Google CAPTCHA Symantec спам конфиденциальная информация инсайдер Perimetrix антивирус тест Anti-Malware Windows 7 операционная система Windows провайдер авторское право RapidShare UNIX свиной грипп шантаж дети EFF BluWiki копирайт экстремизм Panda Security cloud computing McAfee Cybercrime Response Unit Bottle Domains HTTPS ICANN студент шпионское ПО Норвегия школьник New York Times XSS YouTube Warner Music кибершпионаж КНДР Ubuntu свободное ПО AMD ATI касперский Россия РФ сервер хостинг фальшивый антивирус Comodo CA Wi-Fi D-Link суд пароль блог фишинг Одноклассники медведев контрафакт мошенник штраф Sony GPS по Gumblar JAVASCRIPT хакеры вредоносное ПО Yahoo ФАС компьютер Софт MPAA кибероружие PandaLabs Red Hat Минкомсвязи сбой ASUSTeK Computer мошенничество Доктор Веб ВКонтакте Cyber-Arc исходный код PCI DSS МВД фильтр порнография BREIN свобода слова Казахстан GEMA Autodesk сисадмин Gmail кредитная карта кибермошенник LiveJournal шифрование криптография Deep Purple банк нанотехнологии Wikipedia zero-day ColdFusion выборы кража данных DNS BIND Android BASIC атака Black Hat Mac OS X Click Forensics Clampi домен фсб Прокуратура Уголовное дело icq Barrelfish киберпреступность Sophos AT&T ошибка Electa Gamma Knife OpenBSD DARPA военные Сайт Visual Studio 2010 .NET Framework 4 Chrome OS электронная почта турция конференция спамер FTC полиция российская ОС Koobface Великобритания БЕЛОРУССИЯ грузия BSA Bittorrent облачные вычисления Azure Европа Dr.Web Билл Гейтс спецслужбы Cryzip Живой Журнал Royal Bank of Scotland смартфон Canonical Pwn2Own F-Secure Symbian Hotmail фильм

Главная » Статьи » Общие Статьи

Наперегонки со временем: уменьшаем время отклика приложений в Linux
В зависимости от частоты процессора, объема свободной оперативной памяти и скорости работы видеоподсистемы стандартное ядро Linux имеет время отклика в диапазоне от 10 до 100 мс (ядра серии 2.2.* даже до 150 мс), чего вполне достаточно для обычного использования. Но существуют задачи, для которых такая латентность считается невероятно большой. Например, обработка звука требует задержки не более 5 мс суммарно для всей системы, включая реакцию периферийных устройств. Давай разбираться, как можно уменьшить это значение в пингвине.
О чем это мы?

Работая на компьютере, нам постоянно приходится сталкиваться с различного рода задержками. Попробуй одновременно компилить ядро, слушать музыку, качать фильмы по сетке и набирать текст в OpenOffice.org. Я уверен, что рано или поздно ты столкнешься с тем, что знаки во Writer станут появляться через пару секунд после того, как ты нажмешь на кнопки клавиатуры, да и проигрыватель начнет постоянно заикаться. Как же можно уменьшить время отклика приложений в Linux - операционной системе разделения времени, где все процессы равны (ну, почти)? Ведь она разрабатывалась с упором на оптимизацию системной производительности в целом, и об обеспечении ограниченного времени ответа приложениям речи не шло.
Используем подручные средства

Как известно, жизнь системе дают процессы, которые играют ключевую роль в любой операционной системе. Ядро не резиновое, и, несмотря на заоблачные гигагерцовые частоты, в единицу времени можно выполнить инструкции только одного процесса (при этом время использования процессора называют квантом), а самих процессов в системе может быть очень много. Итак, чтобы уменьшить задержки, количество процессов необходимо свести к минимуму. Для этого нужно не только убрать все лишние программы и отключить все неиспользуемые демоны, но и пересобрать ядро, оставив лишь действительно необходимый функционал.

Для того чтобы культурно распределить ресурсы и никого при этом не обделить, в любой системе имеется своя подсистема управления процессами, работающая по принципу «каждому по способностям, каждому по труду». Процесс может работать в двух режимах: в режиме ядра (kernel mode) и в пользовательском режиме (user mode), где он выполняет простые инструкции, не требующие особых «системных» данных. Но когда такие услуги понадобятся, процесс перейдет в режим ядра, хотя инструкции по-прежнему будут выполняться от имени процесса. Все это сделано специально, чтобы защитить рабочее пространство ядра от пользовательского процесса. Остальные процессы либо готовятся к запуску, ожидая, когда планировщик их выберет, либо находятся в режиме сна (asleep), дожидаясь недоступного на данный момент времени ресурса. С последним все просто. Когда поступает сигнал с подконтрольного устройства, процесс объявляет себя TASK_RUNNING и становится в очередь готовности к запуску. Если он имеет высший приоритет, то ядро переключается на его выполнение.

Но есть еще одна заковырка. При предоставлении процессу системных ресурсов происходит так называемое переключение контекста (context switch), сохраняющее образ текущего процесса (на что, кстати, тоже требуется какое-то время, поэтому латентность даже в идеальном случае не будет равна нулю). Так вот переключение контекста, когда процесс находится в режиме ядра, может привести к краху всей системы. Поэтому высокоприоритетному процессу придется терпеливо подождать момента перехода в режим задачи, а это может произойти в двух случаях: работа сделана или необходимый ресурс недоступен. То есть, чтобы обеспечить меньшее время отклика, необходимо свести к минимуму число ядерных задач. Но за такое решение приходится платить общей стабильностью и «тяжестью» кода. В микроядрах это, кстати, реализовано значительно лучше - имеется базовый минимальный набор, остальное навешивается модульно, как на новогоднюю елку, что обеспечивает универсальность и позволяет конструировать системы под конкретные задачи.

Что касается планирования процессов, то оно завязано на приоритете. Планировщик попросту выбирает следующий процесс, имеющий наивысший приоритет. При этом менее приоритетный процесс, выполняющийся в тот момент, может даже полностью не отработать свой квант до конца. Каждый процесс имеет два вида приоритета: относительный (p->nice, по умолчанию до 100 уровней приоритетов), устанавливаемый при запуске приложения, и текущий, на основании которого и происходит планирование. Значение текущего приоритета не является фиксированным, а вычисляется динамически и напрямую зависит от nice. Значение, устанавливаемое пользователем, может находиться в пределах от -20 до +19, при этом приложению с более высоким приоритетом соответствует значение -20, а +10 (по умолчанию) и выше считаются уже низкоприоритетными задачами. Например, для запуска программы с более высоким, чем обычно, приоритетом, делаем так:

$ sudo nice --20 mplayer

А с более низким:

$ sudo nice -20 job &

Чтобы изменить относительный приоритет процесса, следует использовать идентификатор процесса, а не название:

$ sudo renice --20 PID

Кстати, уменьшить время отклика можно, отказавшись от использования утилиты hdparm для дисковых устройств (исключение составляют случаи, когда предвидятся интенсивные операции ввода/вывода, например, обработка аудио- или видеоданных). Так мы получим выигрыш в районе 2 мс.

Текущий приоритет зависит от nice и времени использования системных ресурсов. Он пересчитывается с каждым тиком и во время выхода из режима ядра. В разных системах это происходит по своим формулам, в простейшем случае приоритет просто делится на 2 и при достижении нулевого значения полностью пересчитывается заново (восстанавливается). Такой механизм позволяет получить свое время и низкоприоритетным приложениям, но в итоге высокоприоритетные получают большую его часть.

Каждый компьютер имеет системные часы, которые генерируют аппаратное прерывание через определенные промежутки времени. Интервал между этими прерываниями называется тиком (clock tick). В различных операционных системах тик имеет свое значение. В Linux, как и в большинстве никсов, он составляет 10 мс. Значение можно подсмотреть в файле заголовков include/linux/param.h, в константе HZ. Для тика 10 мс значение HZ равно 100. Чем эта цифра больше, тем чаще тикает планировщик. Тик - одна из высокоприоритетных задач, которая должна занимать минимум времени. За время тика происходит просмотр статистики использования процессора, перепланирование процессов, обновление системного времени (CLOCKS_PER_SEC), отработка необходимых системных процессов, отложенных вызовов и алармов (посылка определенного сигнала процессу через запрашиваемое им время).

Все эти тонкости использовались в различных патчах реализации lowlatency для ядра 2.4. Заменялись не только алгоритмы пересчета текущего приоритета, но и все возможные константы (например, предел nice увеличивали до 256), кроме того, устанавливался таймер с частотой вплоть до 1000 HZ. Пример такого решения найдешь на странице www.zip.com.au/~akpm/linux/schedlat.html.

Для того чтобы указать на приложение, которое требует особого внимания со стороны процессора, можно использовать и заложенный в спецификации POSIX real-time вызов SCHED_FIFO (нечто вроде перехода в режим «мягкого» реального времени). Подобный результат достигается при использовании вызовов SCHED_RR, CAP_IPC_LOCK, CAP_SYS_NICE или через подмену значения sys_sched_get_priority_max - функции, возвращающей максимальный real-time приоритет. Именно использование SCHED_FIFO приводит к тому, что проигрыватель xmms, запущенный под root, практически не заикается даже при запредельных нагрузках на систему.
Выгружаемое ядро

Основной проблемой real-time является возможность захвата ресурсов у низкоприоритетного процесса, особенно если он выполняется в режиме ядра. Ведь даже на переключение контекста тратится некоторое время. Сотни разработчиков по всему миру пытались применить милиарды технологий: от возможности прерывания во время исполнения в ядерном режиме (preemptible kernel, выгружаемое ядро) до временного наследования (inherit) приоритета реального времени низкоприоритетным приложением, чтобы он мог поскорее закончить критический раздел кода и отдать управление.

Тема выгружаемого ядра заинтересовала общественность еще в период господства ветки 2.2. Линус Торвальдс сказал, что real-time - плохая идея, и до поры preemptible реализовывалось исключительно с помощью патчей. Но уже при подготовке ветки 2.6 в исходный код была добавлена возможность сделать ядро выгружаемым (PREEMPT_RT). Preemptible-kernel реализуется, как правило, в виде второго ядра. Если процесс обращается к нему с запросом, основная система фактически блокируется на время его выполнения. Исполняется все это в виде загружаемого модуля, который подменяет/перехватывает наиболее критичные функции, способные привести к задержкам. Но не все так просто. В своем интервью один из инженеров MontaVista (компании-разработчика одного из real-time решений на базе Linux) заявил, что в ядре 2.6 около 11 000 участков кода просто невозможно сделать preemptible.

В интернете, если хорошенько поискать, можно найти достаточное количество разнообразных патчей, позволяющих реализовать режим реального времени в Linux, но, как правило, большая часть проектов уже устарела и предлагает изменения к ядру 2.4. Например, KURT-Linux (www.ittc.ku.edu/kurt) и RT-Linux (www.rtlinux.org). Обе Линукса используют похожие технологии, и субъективно отличий в их работе не заметно, но в интернете хвалят все кому не лень именно RT-Linux. Найти компьютеры под ее управлением можно на генераторах «Токамак», в больницах Перу, на спутниках NASA и в симуляторах F111-C. Кстати, если в Ubuntu ввести sudo apt-cache search real-time, то ты обнаружишь наличие пакета со старой 3.1pre3-3 версией RT-Linux.
Патчим ядро

Для тестирования задержек следует использовать специальные утилиты. В Сети можно найти несколько решений. Например, latencytest, которая разрабатывалась как раз для измерения общих задержек при обработке мультимедийных данных во время различных потрясений, которые могут возникнуть на обычном десктопе (загрузка процессора сложными вычислениями; трудоемкие операции ввода/вывода: запись, копирование, считывание файла размером 350 Мб; вывод большого количества графики; доступ к системе процессов /proc с обновлением через 0,01 с). Эта утилита считается уже устаревшей, зато вся информация выводится с помощью наглядных графиков, что очень удобно при сравнении результатов. К современным бенчмаркам можно отнести rt-test и pi_tests.

На стандартном ядре запускаем утилиту rt-test, только запустив, мы получаем значение 0,125 мс, при увеличении нагрузки оно возрастает до 15,402 мс. Следует обратить внимание на параметр Criteria, который равен 100 микросекунд. В нашем случае результат теста - FAIL, то есть до real-time еще далеко. Ставим lowlatency-ядро - обычное ядро, но с таймером 1000 HZ и уменьшенным временем отклика:

$ sudo apt-get install linux-lowlatency

Перезагружаемся и запускаем rt-test еще раз.

$ sudo rt-test all

Стартовое значение латентности теперь равно 0,073 мс, а максимальное – 2,907 мс. Уже лучше. Хотя Criteria по-прежнему FAIL, но музычка в Amarok'е при приличной загрузке системы больше не прерывается.

Из всех решений по реализации системы реального времени до сегодняшнего дня дошло только одно, предлагаемое Инго Молнаром. Ходили слухи о том, что выпускаемые им патчи (www.kernel.org/pub/linux/kernel/projects/rt) будут включены в ядро 2.6.22, но пока этого не случилось. Для установки rt поклонникам Fedora достаточно ввести yum install kernel-rt, остальным придется немного покомпилировать. Качаем и применяем патч к своему ядру:

$ wget –c www.kernel.org/pub/linux/kernel/projects/rt/older/patch-2.6.22.1-rt9
$ tar xjvf linux-2.6.22.1.tar.bz2
$ cd linux-2.6.22.1
$ sudo patch -p1 < ../patch-2.6.22.1-rt9
$ make menuconfig

При конфигурировании обнаружится ряд дополнительных параметров. Среди них Tickless System (Dynamic Ticks) (NO_HZ) – динамически изменяемый тик; High Resolution Timer Support (HIGH_RES_TIMERS) – таймер высокого разрешения, почитать о нем можно здесь - www.linuxsymposium.org/2006/linuxsymposium_procv1.pdf. В секции Preemption Mode нас интересует Complete Preemption (Real-Time) (PREEMPT_RT), хотя доступны еще No Forced Preemption (Server) (PREEMPT_NONE), Voluntary Kernel Preemption (Desktop) (PREEMPT_VOLUNTARY), Preemptible Kernel (Low-Latency Desktop) (PREEMPT_DESKTOP). В секции «Block layer - Default I/O scheduler» появился планировщик полностью справедливой очереди CFS.

После перезагрузки системы, введя dmesg, можно увидеть, что ядро стало PREEMPT RT, таймер часов работает нестабильно («Clocksource tsc unstable»), а ps aux показывает наличие большого числа новых процессов. Но нас больше интересует результат работы rt-test. Так вот все наши ухищрения привели к тому, что максимальное значение латентности теперь не превышает 0,07 мс. Вуаля, тест пройден!

Категория: Общие Статьи | Добавил: aka_kludge (22.12.2007)
Просмотров: 2196 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

13:57
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2024 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика