The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Планировщики ввода/вывода и процессов в Linux (io linux scheduler cfq ionice process)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: io, linux, scheduler, cfq, ionice, process,  (найти похожие документы)
From: Сергей Яремчук <grinder@ua.fm..> Newsgroups: Date: Mon, 7 Nov 2010 17:02:14 +0000 (UTC) Subject: Планировщики ввода/вывода и процессов в Linux Оригинал: http://www.tux.in.ua/articles/303 http://www.tux.in.ua/articles/527 Функционально сегодняшнее ядро Linux унифицировано, и при необходимости выставим нужные параметры собрать его как для рабочей станции, так и для суперкомпьютера или встроенного девайса. Многие требования у этих систем отличаются и причем весьма существенно. Наверное поэтому разработчики предлагают альтернативные варианты различных компонентов ядра. Сегодня разберемся с планировщиами ввода/вывода. О чем собственно речь. Вообще в любой системе можно выделить два типа планировщиков выполняющих свои задачи: планировщик процессорного времени и планировщик ввода/вывода. И хотя сегодня идет настоящая битва между разработчиками, предложившими за 2,5 года более 300 вариантов планировщиков CPU, а в ядре 2.6.23 стандартный O(1) проработавший 15 лет, будет (наконец то!!!) заменен на более интерактивный CFS (Completely Fair Scheduler, абсолютно справедливый планировщик), трогать мы их пока не будем. Нас интересуют последние. Так планировщики ввода/вывода (I/O scheduler) являются прослойкой между блочными устройствами и драйверами низкого уровня, его задача планировщика оптимальным образом обеспечить доступ процесса к запрашиваемому дисковому устройству. Не смотря на всю кажущуюся простоту вопроса, это сложная и противоречивая задача. Работа с дисками относится к очень медленным операциям, имеющая к тому же долгое время поиска нужной информации, а процессов терпеливо ожидающих своей очереди может быть очень много. Поэтому алгоритм I/O scheduler должен с одной стороны уметь уменьшать время поиска информации на диске, ведь частое переключение между задачами приведет к тому, что головка диска будет большую часть времени будет просто переходить на разные позиции. Также I/O scheduler должен уметь выдавать информацию в соответствии с приоритетом и гарантировать получение данных приложению за определенное время и в нужном количестве. Чтобы решить эти проблемы, в последнее время используются так называемые конвейерные (elevator) механизмы, в которых данные считываются не в порядке поступления запроса (FIFO, LIFO и других), а по возможности с ближайших секторов. Планировщики I/O ядра 2.6 Планировщик ввода/вывода ядра 2.4 использует один сложный конвейер общего назначения. Хотя он и имеет достаточное количество параметров позволяющих управлять временем ожидания запроса в очереди, его возможностей все равно не хватает для более тонкой настройки под специфические задачи. После многочисленных дискуссий и экспериментов из всего многообразия предложенных разработчиками, в ядро 2.6 было включено уже 4 разных планировщика ввода/вывода, а пользователь может подобрать себе наиболее оптимальный исходя из планируемых задач. Узнать какие планировщики I/O включены в ядро, очень просто достаточно ввести команду: $ dmesg | grep scheduler [ 1.348000] io scheduler noop registered [ 1.348000] io scheduler anticipatory registered [ 1.348000] io scheduler deadline registered [ 1.348000] io scheduler cfq registered (default) В KUbuntu 7.10, как и в любом современном дистрибутиве включены все четыре. Алгоритм CFQ отмечен как default то есть используется по умолчанию, причем так обстоят дела практически во всех в современных дистрибутивах с ядром старше 2.6.18. Чтобы увидеть все эти планировщики в новом ядре при самостоятельной его пересборке необходимо включить следующие параметры: $ grep IOSCHED .config CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_IOSCHED="cfq" Как вы понимаете последний параметр определяет алгоритм, который будет использоваться по умолчанию. Кстати если посмотреть в ядра до 2.6.18 там по умолчанию стоит "CONFIG_DEFAULT_IOSCHED="anticipatory"", например в Ubuntu 6.06 установлено именно так. Кратко о планировщиках Планировщик NOOP самый простой планировщик, обладает минимальными возможностями и выполняет только простые операции объединения и сортировки, но зато и потребляет минимум ресурсов. Он представляет собой очередь FIFO (First In, First Out) то есть он, просто выставляет запросы в очередь в том порядке, в котором они пришли. Предназначен NOOP в основном для работы с не дисковыми устройствами (ОЗУ или флэшдиск) или со специализированными решениями которые уже имеют свой собственный планировщик I/O. В этом случае его простота имеет преимущество перед остальными алгоритмами. Задачей алгоритма Deadline является минимизация задержек ввода/вывода, и обспечивает поведение близкое к реальному времени. В нем использовано 5 очередей ввода/вывода, а планировщик использует алгоритм предельного срока для улучшения производительности постоянно переупорядочивая запросы. Кратко суть алгоритма заключается в том, что операциям чтения всегда отдается предпочтение перед операциями записи. Поэтому в настройках по умолчанию операция чтения будет выполнена максимально через - 500 мс, а записи - 5 с. Далее из очереди извлекается следующий процесс, который и получает практически монопольный доступ к ресурсу, затем он переводится в состояние ожидания, а планировщик выбирает следующую программу. Появившись в 2002 году, этот алгоритм сразу был включен в стабильную ветку ядра. Данный алгоритм больше подходит для систем, в которых количество считываемой информации превосходит количество записываемой, например базы данных или веб-сервер. При больших последовательных операциях чтения этот планировщик превосходит CFQ, о котром ниже. Теоретически для десктопа он подходит меньше, так как пока один процесс пользуется диском, все остальное практически замирает. Планировщик Anticipatory (упреждающий конвейер) основан на Deadline, его алгоритм позволяет минимизировать перемещение головки по диску. Для этого перед запросом вводится некая управляемая задержка, при помощи которой достигается переупорядочение и объединение операций обращения к диску. Поэтому есть вероятность того, что предыдущий запрос успеет получить нужные данные, до того как головка диска будет вынуждена перейти на новый сектор. Хотя результатом работы Anticipatory может быть увеличение времени задержки выполнения операций ввода/вывода, поэтому его лучше всего использовать на клиентских машинах с медленной дисковой подсистемой, для которых более важна интерактивность работы, чем задержки ввода/вывода. Этот алгоритм использовался по умолчанию в ядрах 2.6.0 - 2.6.17. И наконец CFQ (Completely Fair Queuing) появился как расширение к сетевому планировщику SFQ (stochastic fair queuing) предназначенного, который в свою очередь был одной из альтернатив упреждающего конвейера. Этот алгоритм был включен в ядро 2.6.6 в апреле 2004. В CFQ для каждого процесса поддерживается своя очередь ввода/вывода, а задача планировщика состоит в том, чтобы как можно равномерней распределять доступную полосу пропускания между всеми запросами. В последних применен принцип time slice, аналогичный используемому в планировщике процессов, поэтому он несколько стал похож на Anticipatory. Время выдаваемое каждому процессу на работу с устройством и число запросов зависит теперь и от приоритета. Поэтому CFQ идеально подходит для случаев, когда множество программ могут потребовать доступ к диску и для многопроцессорных систем, которым требуется сбалансированная работа подсистемы ввода/вывода с различными устройствами. За период развития ядра 2.6 алгоритм CFQ несколько раз совершенствовался и сегодня уже известна четвертая версия. Кстати разработкой всех этих алгоритмов занимается один и тот же человек - Jens Axboe. Изменение планировщика Если нужный алгоритм ядром поддерживается, переключить планировщик на другой очень просто и это можно сделать двумя способами. Первый - добавить параметр elevator в строку kernel конфигурационного файла загрузчика с указанием алгоритма - as, deadline, noop или cfq. Второй - изменить алгоритм на лету, записав в файл /sys/block/<block_device>/queue/scheduler нужную строку. Смотрим что есть в этом файле: $ cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq] Изменим cfq например на anticipatory: $ sudo echo anticipatory > /sys/block/sda/queue/scheduler Стоит помнить, что выбранный планировщик вступит в действие не сразу, а лишь через некоторое время. С выходом CFQ v3 в Linux 2.6.13 появилась возможность выставлять приоритеты использования дисковой подсистемы для процессов, чего раньше не хватало. Подобно утилите nice, которая используется для назначения приоритетов использования процессора, приоритеты ввода/вывода указываются при помощи ionice. В Ubuntu она входит в пакет 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 Небольшой эксперимент Попробуем провести несколько тестов. Для начала запустим программу для тестирования dbench c имитацией работы 50 клиентов "dbench -t 60 50". Получаем Cfg - 88,02 Мб/с, anticipatory - 81,14 Мб/с, Deadline - 134,66 Мб/с, noop - 63,15 Мб/с. Естественно все это прогонялось несколько раз, полученный результат усреднялся. Теперь другая утилита iostat (в Ubuntu требуется установить пакет sysstat), которая умеет показывать сколько блоков было прочитано и записано на диск. Запускаем: $ iostat -p Для CFQ результат скорость считывания 3078,25 блоков в секунду, записи - 257,10. Для anticipatory соответственно - 2337,40 и 208,31, NOOP - 2100,70 и 201,23, deadline - 1981,75 и 195,83. Синтетические тесты не интересны, чтобы с иммитировать ситуацию, приближенную к реальной коммандой создадим файл размером 1 Гб и замерим время сначала в спокойной системе, а затем при просмотре фильма. $ time dd if=/dev/zero of=test bs=1024 count=1024000 Компьютер с Athlon X2 и SATA диском показывал результаты, отличающиеся приблизитительно на 2-3 Мб/с, что можно отнести к погрешности измерения. Поэтому был взят старый системный блок с 633 Целероном и ATA диском. Здесь уже результаты интересней и говорят сами за себя. При Anticipatory файл был создан (вообще то скопирован) со скоростью 9,2 Мб/с, а при запущенном видео уже за 5,0 Мб/с. Выбрав NOOP я устал ждать, так как скорость составила 1,0 Мб/с, а с видео - 973 кб/с. При этом практически прекратилось воспроизведение фильма. Идем далее Deadline результат 8,9 и 7,5 Мб/с, и CFQ - 9,7 и 8,1 Мб/с Результаты вроде понятны и без комментариев, но вообще однозначно сказать какой алгоритм лучше тяжело. В любом случае следует подбирать планировщик изходя из конкретных условий. Например, хотя Deadline и обогнал все остальные в первом тесте, но попытка запустить Amarok или сохранить файл, приведет к тому, что некоторое время придется подождать. А вообще выбор это всегда хорошо. Linux forever! Планировщики процессов Linux В статье Планировщики ввода/вывода Linux были рассмотрены планировщики I/O. Еще одной из важных задач по обеспечению нормальной работы любого сервиса, помимо доступа к дисковым устройствам является доступ к процессору. За распределение процессорного времени между работающими приложениями занимаются другие планировщики. На первый взгляд это простая задача, но если учесть что на современных компьютерах может выполняться сотни, а то и тысячи процессов, то неправильная его реализация может уменьшить общую производительность системы, так как даже на переключение контекста приложения процесса тратится драгоценное и при чем относительно не малое время. Планировщик сталкивется с такими противоречивыми задачами как ограниченное время ответа для критических задач, при увеличении количества процессов борющихся за CPU. Долгое время в Linux присутствовал фактически один scheduler - O(1). Да были другие предложения вроде Staircase от Кона Коливаса (Con Kolivas, http://ck.kolivas.org/patches/pre-releases/2.6.21-rc7/2.6.21-rc7-ck1/patches/), с мая 2007 его разработка прекращена. Или Fairsched (http://sourceforge.net/projects/fairsched). Но все они были реализованы исключительно в виде дополнений, не попадая основную ветку. Сегодня наметилась явная активность разработчиков в этом направлении. Сообщения о новых реализациях появляются на KernelTrap чуть ли не ежемесячно. Стандартному планировщику O(1) уже более 15 лет. В июле 1993 года Линус Торвальдс в своем сообщении (http://kerneltrap.org/mailarchive/linux-activists/36335) описал принцип работы планировщика задач Linux. Оригинальный файл этого планировщика sched.c содержал всего 254 строки кода. Это был простой и понятный алгоритм. В 1996 году нем было уже более 6 тысяч строк. Только через 10 лет в 2002 году первое глобальное изменение ultra-scalable O(1) scheduler от Инго Молнара (Ingo Molnar). В последних версиях sched.c содержит уже более 7000 строк. Алгоритм работы O(1) очень прост. Каждая задача имела фиксированное число (tick), которое пересчитывается с каждым системным тиком (по умолчанию 100 Hz), при выходе из режима ядра или при появлении более приоритетной задачи. Алгоритм просто делит число на два и добавляет базовую величину (по умолчанию 15, с учетом величины nice). Когда тик становится равным 0, он пересчитывается. Кроме этого каждый процессор имеет две очереди. В одной находятся готовые к запуску задачи, во вторую помещаются отработавшие и спящие задачи, которые например, ожидают не доступного в настоящее время ресурса. Когда первая очередь пустеет, очереди меняются местами. Поэтому время работы алгоритма постоянно и не зависит от количества процессов. Современная реализация O(1) используют уже более сложные алгоритмы, анализируя среднее время сна процесса, чтобы обнаружить интерактивные задачи ожидающие ответа пользователя и стараясь задержать их подольше в активном дереве. В ядро 2.6.23 после трех месяцев обкатки в экспериментальной -mm ветке ядра, был включен в качестве основного планировщик CFS (Completely Fair Scheduler, абсолютно справедливый планировщик). Алгоритм которого полностью пересмотрен и весьма сложен. В отличие от O(1) CFS равномернее распределяет процессорное время (фактически если задачи две, то каждая получит ровно 50% CPU), распределяет задачи по нескольким ядрам и имеет меньшее время отклика. Для настройки CFS используется файл /proc/sys/kernel/sched_granularity_ns, в котором по умолчанию установлен режим desktop (меньшее время задержки), но при необходимости его можно переключить в server. $ cat server > /proc/sys/kernel/sched_granularity_ns Con Kolivas остановив разработку ветки ck, в марте анонсировал совершенно новый планировщик RSDL (Rotating Staircase DeadLine scheduler), в последствии он был переименован в SD (Staircase Deadline, ck.kolivas.org/patches/staircase-deadline). За его основу был взят Staircase. Задача нового планировщика исключить зависания присущие O(1), здесь все процессы равны, каждому дается своя квота, исчерпав которую он опускается на следующий уровень приоритета, где получает новую квоту. Причем каждый уровень также имеет свою квоту, если ее исчерпает хотя бы один процесс, все перейдут на следующий уровень, в не зависимости от того отработали ли они свою квоту или нет. Планировщик также пытается определить интерактивные процессы, автоматически повышая им приоритет. Версия SD показывала неплохие результаты на серверах, и поговаривали, что этот планировщик будет включен в основную ветку начиная с 2.6.22, но из-за проблем со здоровьем разработка шла относительно медленно и Инго Молнар обогнал соперника. Как ответ на сложность CFS Роман Зиппель (Roman Zippel) представил рабочий прототип базового алгоритма нового планировщика RFS (Really Fair Scheduler, kerneltrap.org/RFS), который помещает задачу в виртуальную (нормализованную) time line, в которой имеет значение только относительное расстояние между двумя любыми задачами. После некоторых споров в ответ на этот прототип Инго Молнар представил свою версию, которую он назвал RSRFS (Really Simple Really Fair Scheduler) реализованный поверх CFS, и включающий алгоритм из RFS. Есть и патчи к CFS, например programming.kicks-ass.net/kernel-patches/sched-cfs. За последние 2,5 года было предложено около 300 алгоритмов, так что вряд ли здесь будет спокойно в ближайшее время. Проект DeskOpt Интересный проект был представлен примерно полгода назад в списке рассылки разработчиков ядра Linux. Программа DeskOpt (www.stardust.webpages.pl/files/tools/deskopt) представляет собой демон, написанный на языке высокого уровня Python, который отслеживает запускаемые пользователем приложения и автоматически выбирает оптимальные параметры работы планировщика процессов CFS и планировщик ввода/вывода (CFQ, anticipatory, deadline). Все настройки осуществляются путем редактирования конфигурационного файла, в котором по умолчанию описано три класса оптимизации: игры, просмотр видео и прослушивание музыки. Текущая версия 0.6-rc1 от января 2008 года. DeskOpt легко устанавливается Требования: - Python 2.x (http://python.org/) - elementtree (http://effbot.org/downloads/#elementtree) $ tar xjvf deskopt-006-rc1.tar.bz2 $ cd deskopt-006-rc1 $ cp deskopt /usr/local/bin/ $ sudo mkdir /etc/deskopt/ $ sudo cp deskopt.conf /etc/deskopt/ $ sudo cp deskopt.rc /etc/init.d/ К онфигурационный файл имеет простой XML формат, в нем уже есть готовые настройки. В простейшем случае команда выглядит так: $ sudo deskopt -c /etc/deskopt/deskopt.conf

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Ваш комментарий
Имя:         
E-Mail:      
Заголовок:
Текст:





  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor