Масштабируемость Windows 2000 на многопроцессорных системах Часть 2

В первой части статьи я рассказывал о новых возможностях масштабирования операционной системы Windows 2000 с поддержкой приложений, интенсивно использующих физическую память. Нововведения, реализованные разработчиками Microsoft, позволяют приложениям напрямую адресовать до 64 Гбайт физической памяти. Кроме того, благодаря оптимизации алгоритмов увеличен объем специализированной памяти, в том числе неперемещаемой памяти ядра и виртуального кэша файловой системы.

На этот раз речь пойдет о применении средств масштабирования Windows 2000 при работе на многопроцессорных системах. Операционная система может использовать несколько процессоров, однако это не означает, что она хорошо масштабируется. Реальная масштабируемость при работе на многопроцессорных системах достигается лишь в том случае, если разработчики программного обеспечения учитывают необходимость масштабирования на всех стадиях процесса создания ПО. Это касается и собственно серверных приложений, включая операционную систему, и промежуточного ПО, и служб разного уровня. Если любая из перечисленных составляющих серверного приложения проектировалась без учета многопроцессорной масштабируемости, все приложение не будет масштабируемым. Компания Microsoft лишь в очень малой степени может влиять на разработку программного обеспечения независимыми поставщиками промежуточного ПО и приложений, однако масштабируемость самой Windows 2000 — важнейший аспект ее разработки.

Поддержка многопроцессорности

Перед тем как рассматривать реализованные в Windows 2000 возможности поддержки симметричной многопроцессорной обработки (Symmetric Multiprocessing, SMP), я расскажу о некоторых теоретических и лицензионных ограничениях различных версий Windows 2000. Чтобы показать, изменилось ли что-нибудь по сравнению с предыдущей версией - Windows NT 4.0, напомню сначала ее возможности в плане многопроцессорной обработки. NT4.0 поставляется в трех базовых вариантах: NT Workstation, NT Server и NT Server Enterprise Edition (NTS/E). Все три версии используют одно и то же ядро, но в каждом конкретном случае ядро системы конфигурируется по-разному, в зависимости от редакции ОС. Теоретически ядро NT 4.0 в состоянии поддержать работу 32-процессорных систем. Ограничение, связанное с числом 32, вызвано тем, что в ряде внутренних процессов для выбора используемых процессоров ядро NT 4.0 использует 32-разрядные значения (каждый бит такого значения соответствует одному процессору). Например, маска Idle указывает ядру, какие процессоры в данный момент не заняты. Для каждого свободного процессора NT устанавливает соответствующий бит маски равным 1, а для активных процессоров соответствующие биты равны 0. Поскольку NT 4.0 является 32-разрядной ОС, использование 32 разрядов для этих целей вполне естественно.

Однако несмотря на то, что средства ядра NT 4.0 в состоянии поддерживать работу 32 процессоров, этого не допускали лицензионные ограничения. Значение параметра реестра HKEY_LOCAL_MACHINESYSTEM CurrentControlSetSession ManagerLicensedProcessors соответствовало максимальному числу процессоров, которое имело право использовать ядро. Для версии NT Workstation 4.0 это значение равно 2; для NT Server 4.0 оно увеличено до 4, а для ОС NTS/E равняется 8. Поставщики готовых систем на базе NT с числом процессоров более восьми поставляли своим заказчикам OEM-версии NT, специально лицензированные Microsoft для поддержки необходимого количества процессоров.

В отношении теоретических и лицензионных ограничений поддержки многопроцессорности операционная система Windows 2000 ничем не отличается от NT 4.0. Ядро Windows 2000 по-прежнему использует 32 разряда для идентификации процессоров. Microsoft лицензировала версию Windows 2000 Professional (Win-dows 2000 Pro) — эквивалент NT Workstation 4.0 — для использования максимум двух процессоров. Оперативная система Windows 2000 Server лицензирована для работы на четырех процессорах, а Windows 2000 Advanced Server (эквивалент ОС NTS/E) — для восьмипроцессорных систем. Windows 2000 Datacenter Ser-ver (Datacenter), аналога которой в семействе NT 4.0 нет, поддерживает до 16 процессоров. Как и в случае с NT 4.0, производители оборудования могут поставлять OEM-версии Windows 2000 для 32-процессорных систем.

Квантование и классы планировщика

Системный планировщик Windows 2000 является многозадачным планировщиком с приоритетным режимом обслуживания. Это означает, что он делит процессорное время между активными потоками системы. Планировщик предоставляет каждому потоку некоторый квант времени работы процессора. Если поток по каким-то причинам преждевременно перестает быть активным (например, когда останавливается в ожидании завершения операции ввода/вывода), ядро Win-dows 2000 вызывает планировщик для поиска следующего потока, которому можно передать управление процессором. Если поток выбирает весь отведенный ему квант времени, Windows 2000 вызывает планировщик с тем, чтобы другие потоки также могли выполнять свою работу. Планировщик Windows 2000 (который в Microsoft называют диспетчером) с помощью системы приоритетов устанавливает, какому именно из активных потоков в каждый момент времени следует передать управление одним из процессоров системы. Планировщик всякий раз выбирает поток с наивысшим приоритетом; если сразу несколько потоков имеют одинаковый приоритет, планировщик предоставляет квант процессорного времени каждому из них по очереди. Переключение процессора с выполнения команд одного потока на выполнение команд другого называют переключением контекста.

Приоритет процесса, породившего поток, определяет и приоритет самого потока. Приоритеты имеют значения от 1 до 31. Разработчики приложений или системные администраторы могут манипулировать уровнем приоритета процесса, приписывая процесс к одному из нескольких возможных классов. Каждый класс содержит значения приоритетов определенного диапазона, и операционная система Windows 2000 интерпретирует установку приоритета потока - средствами программного интерфейса или же с помощью специальных административных утилит — как изменение приоритета процесса. Операционная система NT 4.0 предоставляет четыре класса приоритетов: Realtime, High, Normal и Idle. Класс Realtime содержит приоритеты высшего уровня. И разработчики, и администраторы пользуются им сравнительно редко, поскольку потоки с приоритетом из этого диапазона соперничают с потоками ядра ОС. Таким образом, большинству приложений доступны лишь три оставшихся класса. Часто разработчикам и администраторам бывает необходима большая дискретность в назначении уровня приоритета индивидуальных потоков или приложения в целом, в зависимости от задачи, выполняемой конкретным потоком или приложением. В ответ на подобные пожелания разработчики Windows 2000 ввели два новых класса приоритетов: Below Normal и Above Normal. На Рисунке 1 изображен весь спектр классов с описанием приоритетов процессов.

В Microsoft квант потока Windows 2000 соотносят с временными интервалами (clock ticks) планировщика. Длительность единичного интервала определяет системный модуль уровня аппаратной абстракции (Hardware Abstraction Layer, HAL); типичная продолжительность интервала составляет 7, 10 и 15 мс. Короткое квантование подходит для систем, которые обслуживают большое число интерактивных приложений и должны часто откликаться на действия пользователя. Более продолжительное квантование лучше использовать в системах, на которых выполняется небольшое число серверных приложений, не взаимодействующих с пользователем, поскольку уменьшение числа переключений контекста повышает общую производительность системы.

В NT Workstation 4.0 планировщик присваивал потокам неактивных окон и приложениям, не использующим окна, продолжительность кванта, равную двум интервалам планировщика. Активные приложения получали кванты продолжительностью два, четыре и шесть интервалов в зависимости от положения ползунка на вкладке Performance модуля System панели управления. Крайнее правое положение ползунка соответствует шести интервалам на квант (максимальная производительность активных приложений). Операционная система NT Server 4.0 назначала квант длительностью 12 интервалов планировщика всем потокам всех — а не только активных — приложений. Ползунок присутствовал и в NT Server 4.0, но его положение никак не влияло на длительность кванта.

Экран 1. Диалоговое окно настройки производительности Performance Options.

Хотя длительности квантов NT 4.0 вполне адекватны типичным ситуациям использования NT Workstation и NT Server, бывают случаи, когда продолжительность кванта не соответствует решаемой задаче. В такие моменты падает производительность работы приложений, снижаются масштабируемость и скорость реакции системы при взаимодействии с пользователем. Windows 2000 предоставляет администраторам возможность выбрать оптимальную продолжительность кванта для текущей нагрузки в любой версии. Диалоговое окно Performance Options (модуль System панели управления), показанное на Экране 1, позволяет администратору оптимизировать производительность приложений или фоновых служб. При оптимизации производительности приложений продолжительность кванта задается так же, как в NT Workstation 4.0 (т. е. фоновые потоки получают квант продолжительностью в два интервала планировщика, а активные приложения — шесть). Оптимизация производительности работы фоновых служб аналогична назначению квантов в NT Server 4.0 (квант длиной 12 интервалов для всех приложений).

Объект «задание»

На сервере обычно работает несколько связанных процессов, взаимодействующих друг другом в ходе решения некоторой вычислительной задачи или обработки данных. Например, системы поддержки принятия решений часто требуют совместной работы СУБД, клиентского ПО базы данных, промежуточного программного обеспечения и специализированных аналитических приложений. В таком случае сервер должен выполнять все эти приложения параллельно. При работе с сервером БД или Web-сервером реализуется иной сценарий — часть операций выполняется в фоновом режиме, в то время как активные приложения обслуживают взаимодействие с клиентом. Таким образом, весьма желательно, чтобы у администратора или программиста была, с одной стороны, возможность управлять приоритетами всех процессов приложения как единым целым и, с другой, ограничивать характеристики различных потоков приложения, чтобы избежать конкуренции между прикладными и серверными процессами. Например, администратор системы может при необходимости назначить низкий приоритет планировщика всем фоновым процессам, чтобы минимизировать их влияние на выполнение активных заданий.

Несмотря на наличие интерфейсов для управления отдельными процессами, в NT 4.0 практически не было программных и административных средств управления группой связанных процессов. Управление приложениями было осложнено необходимостью программным путем выяснять, какие именно процессы входят в группу, особенно если приложение динамически создает новые процессы. К сказанному остается добавить, что в NT 4.0 изменение приоритета процесса — практически единственный метод ограничения использования процессами ресурсов системы.

Рисунок 2. Схема объекта «задание».

Разработчики Microsoft добавили в Windows 2000 новый объект — задание (Job Object). Он представляет собой контейнер для родственных процессов, а программный интерфейс Job Object API позволяет управлять всеми процессами задания и предоставляет несколько способов ограничения использования ресурсов системы. На Рисунке 2 приведен пример объекта «задание». Группа связанных процессов может содержать специальный код управления группой. С другой стороны, администратор с помощью специальных утилит может управлять набором приложений как единым заданием. Например, компания Sequent выпустила специальную утилиту для управления заданиями, которую разработчики Microsoft планируют включить в состав Windows 2000 Datacenter.

Разработчик с помощью функции AssignProcessToJobObject прикладного интерфейса JobObject может добавить процесс к объекту «задание». Если процесс включен в состав объекта «задание», его уже нельзя оттуда удалить. И, если только программист не решил иначе, все дочерние процессы и все процессы, созданные процессом задания, также принадлежат заданию, в состав которого входит этот процесс. Функция API Terminate-JobObject позволяет одновременно завершить работу всех процессов задания. Другой API предоставляет разработчику возможность связать с объектом «задание» объект синхронизации. С помощью синхронизирующего объекта «задание» может получать уведомления о различных событиях, таких, как добавление нового процесса или нормальное/ошибочное завершение процесса задания. Основой для работы с объектом «задание» служат функции QueryInformationJobObject и SetIn-formationJobObject. Они позволяют приложению отслеживать использование ресурсов системы процессами задания и накладывать ограничения на использование ресурсов и другие характеристики, связанные с производительностью.

Рисунок 3. Типы ограничений объекта «задание».
Привилегии маркера доступа

Идентификаторы безопасности маркера доступа (SID)

Активные процессы

Доступ к буферу обмена

Доля процессорного времени задания

Распределение памяти задания

Максимальный размер рабочего набора процесса

Минимальный размер рабочего набора процесса

Распределение памяти процесса

Класс приоритета процесса

Класс планировщика

Установки дисплея

Доступ к окнам и рабочему столу

Доля процессорного времени процесса

На Рисунке 3 представлены различные виды ограничений, которые поддерживает объект «задание», включая ограничение на использование физической памяти и долю процессорного времени, число процессов, а также различные ограничения, связанные с защитой. Например, программист указывает, что некоторый процесс задания не может использовать больше заранее оговоренного объема виртуальной памяти или же что общее использование физической памяти процессами задания не должно превышать некоторого предельного значения. Когда задание выбирает всю отведенную ему память, диспетчер памяти Windows 2000 не выделяет ему дополнительный ресурс. API задания предоставляет разработчику две возможности обработки ситуации, когда задание исчерпает выделенное ему процессорное время. Во-первых, Windows 2000 может завершить работу всех процессов задания. Во-вторых, операционная система может передать сообщение в порт завершения объекта «задание», если таковой существует.

Ограничения, связанные с защитой, которые программист может наложить на объект «задание» с помощью API задания, весьма гибки. Например, бывает нежелательно предоставлять фоновому заданию возможность перезагрузки сервера. Наличие у задания подобного права определяется маркером доступа процессов задания — именно он отражает полномочия учетной записи, от имени которой запущено задание. Один из методов ограничения прав процессов — исключение определенных привилегий из маркеров доступа процессов задания. Программист может лишить процессы задания права на перезагрузку сервера или других привилегий, чтобы гарантировать нормальную работу сервера независимо от «поведения» задания. Еще один метод ограничения прав задания — удаление связи с учетными записями, от имени которых оно запущено. Пусть, например, задание запущено от имени пользователя, учетная запись которого принадлежит к группе Administrators. В этом случае пользователь может удалить из маркеров доступа процессов задания все права группы Adminis-trators, чтобы процессы не смогли получить доступ к критическим ресурсам системы, таким, как файлы, устройства и синхронизация объектов, — обычно правом доступа к таким ресурсам обладают только администраторы системы.

Объект «задание» позволяет управлять многими характеристиками, связанными с производительностью, включая классы приоритетов процессов и длительность квантов потоков. Например, можно одновременно установить класс приоритета всем процессам задания, что позволяет добиться необходимого соотношения между производительностью задания и системных процессов. Если нужно, чтобы задание выполнялось в фоновом режиме, ему можно назначить класс с низкими приоритетами — такой, например, как Below Normal. В Windows 2000 длительность кванта процессов задания определяется присвоенным ему классом планировщика — от 0 до 9. В Windows 2000 Server разным классам соответствует разная продолжительность кванта; в Windows 2000 Pro класс планировщика не используется.

В Таблице 1 приведены размеры квантов для каждого класса планировщика. Любопытно, что, если присвоить девятый класс планировщика процессу класса Realtime, длительность кванта процесса (потока) становится неограниченной. Другими словами, планировщик Windows 2000 никогда не закончит работу потока с приоритетом выше 15 и классом планировщика 9. Программистам и системным администраторам необходимо соблюдать осторожность с подобного рода назначениями. Для установки значения класса планировщика выше 5 необходимо право повышения базового приоритета, поскольку при этом длительность кванта превышает обычное значение для стандартных процессов.

Благодаря объекту «задание» в Windows 2000 появился мощный и гибкий механизм управления группами связанных процессов. Кроме того, параметры задания, относящиеся к производительности и использованию ресурсов системы, либо могут способствовать росту производительности отдельного задания, либо (что скорее всего) позволят системе в целом добиться лучшей масштабируемости за счет ограничения возможностей отдельных заданий.

Пул потоков

Практически каждое приложение, проектируемое с целью обеспечения масштабируемости при работе в многопроцессорной среде, поддерживает асинхронный ввод/вывод и создает множество взаимодействующих друг с другом потоков. Если приложение использует только один поток, оно в каждый момент времени может работать только на одном процессоре. С другой стороны, если число потоков приложения равно числу процессоров в системе, оно может выполняться одновременно на всех процессорах системы, поддерживающей симметричную многопроцессорную обработку. Асинхронный ввод/вывод позволяет потокам приложения инициировать операции ввода/вывода и при этом не простаивать в ожидании окончания этих операций, а выполнять другую работу.

Разработка многопотокового кода — утомительное занятие, особенно если она необходима лишь для некоторых частей приложения или если разработчик планирует организовать соответствие числа потоков нагрузке на приложение. Слишком большое число потоков, как и слишком малое, обязательно приведет к снижению производительности. В Windows 2000 появилась возможность организации пула потоков. Для этого специалистами Microsoft был реализован новый прикладной интерфейс, упрощающий работу с потоками.

Каждое приложение обладает собственным пулом потоков, который обслуживается системной библиотекой ntdll.dll (NTDLL). Библиотека kernel32.dll содержит вызовы API Win32, реализующие интерфейс организации пула потоков приложения, но сам программный интерфейс управления потоками находится в библиотеке NTDLL. Приложение использует этот интерфейс для организации пула потоков всякий раз, когда необходимо эффективно решить конкретную задачу, представленную несколькими потоками. Выполнение такой функции может завершаться, например, по таймеру, по окончанию выполнения операции ввода/вывода или просто в связи с тем, что приложение поместило вызов функции в очередь на выполнение. NTDLL динамически создает и удаляет потоки пула по запросу приложения.

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

В экстремальных условиях число потоков каждого типа в пуле может вырасти до максимальной величины — 2000, особенно когда приложение помещает в очередь множество функций с признаком продолжительной активности. Вместе с тем, в нормальных условиях число активных потоков пула обычно не больше 10. Таким образом, приложение может воспользоваться преимуществами многопотоковости, просто переложив работу на пул потоков и предоставив ему самому заботиться об управлении потоками.

Очередь временных блокировок

Помимо рассмотренных выше новых API в Windows 2000 появилось множество нововведений, связанных с поддержкой многопроцессорной масштабируемости. Во-первых, разработчики оптимизировали размещение в памяти кода ядра операционной системы таких важных компонентов, как системные DLL и драйверы. В результате все участки кода, которые выполняются совместно, располагаются поблизости друг от друга, что позволяет снизить нагрузку на подсистему управления памятью. Алгоритм этой новой технологии, названной Lego, состоит из двух шагов. На первом шаге исполняемый код генерирует тест-трассировку базовых блоков (Basic Block Testing, BBT) исполняемого кода. На втором шаге трассировка анализируется, и на основе анализа проводится реорганизация размещения кода в памяти. Именно этот полученный в результате реорганизации исполняемый код и поставляет Microsoft.

Другой подход к оптимизации производительности связан с использованием временных блокировок. Временные блокировки — это объекты синхронизации, которые ядро ОС применяет для синхронизации доступа к структурам данных процессоров в SMP-системах. Например, если ядро операционной системы обращается к БД планировщика одного из процессоров, оно не должно одновременно обращаться к данным БД других процессоров системы. Следовательно, ядро временно блокирует базу данных, прежде чем обратиться к ней, и снимает блокировку после завершения операций, связанных с предыдущим доступом. Если к моменту обращения к БД ядро уже блокировало другой процессор, оно входит в своеобразный «ступор», ожидая снятия блокировки.

Временная блокировка переводит исполнение кода ядра в последовательный режим, тем самым нанося ущерб многопроцессорной масштабируемости, поскольку возможность параллельного выполнения процессов является обязательным условием для нее. Специалисты Microsoft нашли способ точно отслеживать ситуации, когда ядро использует временные блокировки, чтобы прибегать к ним только в тех случаях, когда это действительно необходимо. Более того, разработчики Microsoft ввели новый тип временных блокировок — очередные блокировки.

Очередные блокировки больше подходят для многопроцессорных систем, чем стандартные. Работают они следующим образом: когда процессор нуждается в блокировке, которую удерживает другой процессор, первый процессор помещает свой идентификатор в очередь ожидания блокировки. Когда второй процессор, удерживающий блокировку, освобождает ее, он передает блокировку в распоряжение следующего процессора, ожидающего в очереди. Тем временем процессоры, ожидающие блокировки в глобальной очереди блокировок, непрерывно отслеживают состояние специального флажка процессоров. С его помощью процессор, освобождающий блокировку, сообщает процессору, ожидающему ее, что наступила его очередь.

Таким образом, очередные блокировки вынуждают процессоры анализировать некий многопроцессорный флаг, а не состояние глобальной блокировки. В результате многопроцессорная шина не перегружена трафиком синхронизации процессоров. Кроме того, очередь блокировок «дисциплинирует» процессоры. Очередь блокировок, действующая по принципу «первым пришел — первым ушел», гарантирует более согласованную работу процессоров, обращающихся к одним и тем же блокировкам.

Разработчики Microsoft не стали заменять все блокировки ядра Windows 2000 блокировками нового типа, ограничившись изменением лишь десятка из них. Преобразованы блокировки, которые защищают структуры данных ядра: например, базу данных диспетчера кэша, базу данных планировщика потоков, а также базу данных диспетчера физической памяти. Очередные блокировки, несомненно, обеспечивают Windows 2000 заметное преимущество в масштабируемости по сравнению с NT 4.0.

Масштабируемость промышленного уровня

Учитывая другие нововведения, такие, как поддержки больших объемов памяти, различные API для работы с этими объемами памяти и управления группами процессов как единым целым, а также усовершенствованиями в области управления ресурсами системы и работой процессоров, можно сказать, что Windows 2000 неплохо оснащена для того, чтобы помочь приложениям использовать возможности аппаратного обеспечения систем корпоративного класса. Данная ОС может с успехом применяться в тех областях, где NT 4.0 отставала, и больше соответствовать требованиям систем на базе серверов среднего и высшего класса.

(Окончание.)

МАРК РУСИНОВИЧ - доктор философии и редактор Windows 2000 Magazine. С ним можно связаться по электронной почте по адресу: mark@sysinternals.com, или через Web-узел http://www.sysinternals.com


Таблица 1. Размеры квантов для каждого класса планировщика заданий.
Класс планировщика0123456789
Временные интервалы2468101214161820

назад