Все современные суперкомпьютеры используют параллельную обработку данных. С самого начала компьютерной эры именно этот путь был и остаётся наиболее важным для достижения высокой производительности. Сейчас даже самый простой настольный компьютер если не многоядерный, то уж почти наверняка с технологией simultaneous multithreading (например, HyperThreading от Intel или AMD SMT), позволяющей работать двум (иногда более) программным потокам одновременно. Даже мобильные телефоны и фотоаппараты становятся параллельными и многоядерными.
Принцип параллельной обработки данных прост: если две или более операции независимы (т. е. результаты их выполнения не влияют на входные данные друг друга), то эти операции можно выполнить одновременно, т. е. параллельно. В аппаратуре традиционно есть два варианта воплощения этого принципа – параллелизм и конвейеризация.
Параллелизм – параллельное выполнение машинных команд разными устройствами. Например, команды
x=a+b и y=b*c
, где a
, b
и с
– регистры, процессор может выполнить независимо, если он имеет раздельные устройства сложения и умножения (см. рис. 1). Этот принцип воплощён в большинстве современных процессоров.
Конвейеризация – разделение команд на этапы, каждый из которых выполняется быстро отдельным элементом аппаратуры, и выполнение этих этапов происходит по принципу конвейера: друг за другом. Таким образом, одновременно может выполняться несколько команд на разных стадиях конвейера. Наиболее часто этот принцип используется в векторизации – выполнении однотипной операции над векторами, т. е. массивами данных, расположенными в памяти регулярно (см. рис. 2).
Рис. 1: Параллельное выполнение
Рис. 2: Векторизация + конвейер
Чаще всего элементы вектора расположены друг за другом. Типичный пример – сложение векторов. Так как операция, выполняющаяся над векторами, одна и та же, то её разбивают на фазы – ступени конвейера. Например, загрузка элементов из памяти, нормализация мантисс, сложение, коррекция, запись в память. После выполнения первой ступени над первым элементом вектора эту стадию можно сразу же выполнить над вторым элементом, не дожидаясь завершения всей операции над первым. После завершения каждой ступени над одним элементом можно выполнить её над следующим. Таким образом, если самая медленная ступень конвейера выполняется за
К
тактов, а все ступени – за S
тактов, то вектор из N
элементов обработается за K*(N–1)+S
.
Первый элемент обработается за положенные
S
тактов (это называется «время разгона конвейера»), а потом устройство будет выдавать по одному результату в K
тактов. В современных процессорах чаще всего K=1
. Однако конвейеризация не обязательно подразумевает векторизацию и наоборот. Например, если устройство сложения конвейерное и мы выполняем несколько обычных сложений подряд, они могут отлично задействовать конвейер.
Для системного администратора не всегда нужно доскональное понимание работы процессора, языка ассемблера и умение оптимизировать пользовательские программы, но понимание того, как устроено параллельное выполнение в процессоре, очень важно. Многие современные процессоры многоядерные, т.е. содержат несколько полноценных (или почти полноценных) процессоров на одном кристалле (в одной микросхеме). Естественно, что они могут работать параллельно. Есть ещё параллелизм на уровне доступа к памяти, когда разные банки памяти могут работать независимо, а значит, отдавать или записывать данные быстрее. Есть также параллелизм на уровне работы с устройствами – можно заранее сформировать в памяти блок для записи на диск или для отправки по сети и «скомандовать» контроллеру выполнить запись/передачу. Далее процессор может выполнять другие действия, а данные из памяти в это время будут записываться на диск или пересылаться по сети.
Это параллелизм, заложенный в «железе». Для того, чтобы задействовать его максимально, заставить вычислители (ядра, процессоры, вычислительные узлы…) работать параллельно, необходимо составить программу таким образом, чтобы она использовала все эти ресурсы. Т. е. написать параллельную программу. Этим мы заниматься не будем (по крайней мере, в рамках этой книги), но иметь дело с параллельными программами нам придётся постоянно, и знать, как они работают, нам необходимо.[1]
Если я написал параллельную программу, значит ли это, что она тут же заработает быстрее обычной (последовательной)? Нет. Более того, она может работать даже медленнее. Ведь части, которые должны исполняться параллельно, в реальности могут конфликтовать друг с другом. Например, две нити обращаются к разным участкам памяти и не дают эффективно работать кэшу процессора. Или параллельные процессы постоянно вынуждены ждать данных от самого медленного из них. Или…
Вариантов неэффективного параллельного кода много, и если не удаётся достичь хорошего ускорения программы на суперкомпьютере, то, возможно, она неэффективно использует параллелизм. Выяснить реальную причину очень трудно, для этого необходимо использовать «отладчики производительности» – параллельные профилировщики, трассировщики или хотя бы мониторинг вычислительных узлов, по данным которого можно судить о том, что происходит во время работы программы.
Для нас в первую очередь интересен параллелизм на уровне процессов UNIX (в том числе на разных узлах) и нитей. Именно здесь заложен основной потенциал параллельных приложений. Именно такой параллелизм используют наиболее популярные среды параллельного программирования MPI и OpenMP. Это не значит, что на других уровнях этого потенциала нет, но именно отсюда всегда нужно начинать. Среды (технологии) параллельного программирования представляют собой библиотеки или языки программирования, позволяющие упростить написание параллельных программ.
Для администратора важно знать, как устроена каждая среда, как она реализована технически, так как при возникновении проблем с программами потребуется понять, в чём причина неполадки. Даже если причина – ошибка в программе, нужно уметь показать это пользователю и подсказать ему путь решения проблемы. Параллельные программы, как правило, пишутся в терминах нитей или параллельных процессов (или всего вместе). То есть один и тот же код программы выполняется в разных нитях одного процесса (на разных процессорных ядрах) или в разных процессах, которые могут работать и на разных узлах.
Такой подход позволяет максимально задействовать все процессорные ядра – на каждом выполняется свой процесс или поток. Действия разных процессов в одной программе необходимо согласовать, для этого в средах параллельного программирования предусмотрены разные механизмы: в MPI – передача сообщений, в OpenMP – общие переменные и автоматическое распараллеливание циклов и т. д. Технологии типа MPI – это не только указание особых функций и инструкций в коде, но и среда запуска программы. Особенно это относится к средам, использующим несколько вычислительных узлов, – ведь на каждом узле надо запустить экземпляр (а то и не один) программы и «подружить» его с остальными запущенными экземплярами той же программы (но не соседней). Вот тут и начинаются заботы системного администратора. Все установленные параллельные среды надо оптимально настроить, а при возникновении проблем – уметь расшифровать их диагностику.
Например, в кластере используется скоростная коммуникационная сеть (InfiniBand или другая) и обычный Ethernet для управления. Установленная среда MPI работает, но эффективность работы программ низкая. Нередко причиной является неверная настройка, в результате которой MPI использует медленную управляющую сеть вместо скоростной.
Когда говорят «кластер», подразумевают множество компьютеров, объединённых в нечто единое. Но вариантов этого «нечто» может быть несколько. Они отличаются целью и, как следствие, – реализацией.
Первый вид кластеров – High-Availability, или кластеры высокой доступности. Их задача – предоставить доступ к какому-то ресурсу с максимальной скоростью и минимальной задержкой. Ресурсом обычно выступают web-сайт, база данных или другой сервис. В таком кластере при выходе из строя одного узла работоспособность всего ресурса сохраняется – клиенты сбойного узла переподключаются и получают доступ к ресурсу с другого узла кластера. Очень похожий принцип применяется в «облачных» технологиях: вы не знаете, на каком именно узле будет работать ваше приложение или образ операционной системы, облако само подберёт свободные ресурсы.
Другой вид кластеров – High Productivity. Этот тип похож на предыдущий, но в данном случае все узлы кластера уже работают над одним заданием, разбитым на части. Если какой-то узел отказал, его часть задания отправляется другому; если в кластер добавляются новые узлы, им выделяются не посчитанные ещё части, и общий счёт идёт быстрее. В качестве примеров можно назвать GRID, программы типа Seti@home, Folding@Home. Однако с помощью таких кластеров может быть решён только узкий класс задач. Да и сам кластер для таких задач нередко становится не нужен, можно воспользоваться домашними компьютерами или серверами, связав их через локальную сеть или Интернет.
Третий вид – High Performance (HPC – High Performance Computing). Именно он интересен нам. В отличие от остальных, выход из строя одного из узлов кластера, как правило, ведёт к аварийному завершению параллельной программы, только в редких случаях выполнение программы автоматически продолжается с сохранённой ранее контрольной точки. Именно поэтому, в отличие от предыдущих видов, HPC-кластеры менее устойчивы в работе, и без должного контроля и мониторинга использовать их просто не получится.
Важное отличие этого вида кластеров от остальных – тесная связность всех узлов. Это и самые быстрые сети, соединяющие узлы, и высокопроизводительные параллельные файловые системы, и средства дополнительной синхронизации узлов, и другие средства, важные для параллельных программ. Приложения, работающие на таких кластерах, как правило, работают в модели передачи сообщений между параллельно запущенными процессами. Если запустить их на множестве компьютеров, соединённых медленной сетью, то они бóльшую часть времени потратят на ожидание информации друг от друга.
Идеал, к которой стремятся все производители кластеров, – создать виртуальный компьютер с большой памятью и огромным числом вычислительных ядер. К сожалению, реальность ещё очень далека от идеала, и сейчас любой вычислительный кластер – это всё-таки множество отдельных вычислительных узлов, соединённых быстрой сетью. От сети в таком кластере требуется не только скорость (пропускная способность), но и низкая величина задержек или накладных расходов (латентность). Большинство параллельных программ обмениваются сообщениями часто, а значит, время на инициализацию отправки и приёма сообщения начинает играть большую роль. На сети с большой латентностью некоторые программы могут работать в разы медленнее, чем на сети, где латентность низкая.
Мы только что поговорили о кластерах. Но всегда ли слово «суперкомпьютер» означает кластер? Нет, не всегда. Важная черта кластера – возможность сборки из серийных общедоступных компонентов. Т. е. можно купить все компоненты кластера в магазине и, обладая достаточным опытом, собрать его самостоятельно.
Суперкомпьютер в общем случае – изделие с уникальными компонентами, производимое одним поставщиком. В качестве примера приведём серию Blue Gene компании IBM – архитектура этих машин похожа на кластер, на них доступны те же программные средства, что и на вычислительных кластерах, но купить Blue Gene можно только у IBM или их дистрибьюторов.
Построить Blue Gene самостоятельно невозможно: ключевые компоненты отдельно не продаются. И дело не в марке, а в уникальных технологиях. Кроме Blue Gene есть множество иных серий, иных уникальных разработок. Обратный пример – «вычислительные фермы», т. е. группы компьютеров, работающих над одной задачей, но обычно даже не передающие данные друг другу, или кластеры класса «BeoWulf[2]», т. е. собранные практически из подручных средств.
Как видим, грань между понятиями «кластер» и «не-кластер» достаточно чёткая, но какой кластер считать суперкомпьютером, а какой нет – вопрос размытый. Часто вместо «кластер» говорят более тактично: «обладающий кластерной архитектурой». В этой книге мы будем рассматривать технологии, доступные для всех или большинства. Следовательно, большинство из них будет относится именно к кластерам. Но это не значит, что в вычислительных комплексах, которые мы формально не относим к кластерам, этих технологий не встретится. Большинство современных суперкомпьютеров используют те же наработки, что и кластеры, более того, почти все они построены как кластеры с добавлением особо быстрых сетей, техник работы с общей памятью, синхронизации или иных технологий. А значит, все знания о кластерах вам только помогут.
На первый взгляд, большой кластер ничем не отличается от множества офисных компьютеров, объединённых локальной сетью, и нескольких стандартных серверов – дискового хранилища и т. п. На самом деле отличия есть, и очень важные. Начнём с оборудования – для кластера требования намного выше. Если в локальной сети можно временно заменить сломанный коммутатор на более простой или даже на несколько дней нарушить связность сети (ну, придётся отчёты печатать на втором этаже, потерпите), то в кластере это недопустимо. Заменив IB-коммутатор на GigabitEthernet или узел с 8ГБ памяти на узел с 4ГБ, мы получим неработающий кластер или работающий так, что все пользователи завалят нас жалобами.
Настоятельно рекомендуем иметь ЗИП (аварийный запас) всех ключевых компонент оборудования, если у них нет аппаратного дублирования, и сервисный договор о замене оборудования в чётко оговорённый срок.
Ещё вспомним о том, что кластер, в отличие от офисных компьютеров, упакован на нескольких квадратных метрах (большой – на нескольких десятках, реже – сотнях). Поэтому требования к охлаждению для него намного выше, тут открытым окном или бытовым кондиционером не обойтись. Электричества на суперкомпьютер уходит гораздо больше, чем на много офисных ПК, и бытовых UPS тут тоже не хватит, да и в бытовую розетку и даже в десяток его не включишь.
В современных кластерах вычислительная часть может занимать меньше четверти от всей площади установки, всё остальное занимает климатическое и энергетическое оборудование. А контроль и управление этим оборудованием (но не обслуживание) – тоже часть работы администратора. Более того, в отличие от офиса, если вычислительный узел, кондиционер или UPS вышли из строя, то об этом нельзя узнать от прибежавшего сотрудника, у которого «горит отчёт, а монитор не включается». Хуже всего, если об этом придётся узнать от пользователей, у которых программа перестала работать как надо или запускается два раза из трёх. Эту задачу решает мониторинг всего и вся. Очень важно знать как можно больше о состоянии кластера. На этом отличия не заканчиваются. Одно из самых важных связано с режимом работы. В офисе нагрузка на компьютеры не высока: большая мощность от них требуется несколько минут в день, чтобы отобразить большой документ или проиграть видеоролик новой рекламы продукта. 99% времени эти компьютеры ждут клика мышкой или нажатия на клавишу. В кластере всё принципиально иначе, его нормальный режим работы – 80–100% загрузки каждого узла постоянно.
В офисе даже пиковая нагрузка одного или двух компьютеров не будет заметна на общем фоне. Но каждый опытный администратор знает, что такое «все компьютеры схватили какой-то вирус» – нагрузка на сеть возрастает в сотни раз, сетевое хранилище не справляется с потоком запросов, всё начинает жутко «тормозить»… А в кластере ситуация, когда все узлы, занятые под одно задание, начинают обмениваться данными или писать промежуточные данные на сетевой диск – это не вирус, а совершенно нормальная ситуация. Особый тип пиковой нагрузки – включение. В офисе всё происходит само собой: утром все приходят, кто-то пораньше, кто-то попозже, включают компьютеры, подключают ноутбуки… Для суперкомпьютера же процедура включения означает резкое увеличение энергопотребления на десятки, а то и тысячи киловатт, дружное обращение вычислительных узлов к дисковому хранилищу, сервисным серверам. Если включить всё разом, то, скорее всего, установка просто сгорит. И даже «плавное» включение узлов одного за одним с интервалом в несколько секунд может привести к сетевым конфликтам, перегрузке какого-то сервиса запросами.
Для примера: в больших дисковых массивах (из нескольких стоек) полки и диски запускаются поочерёдно в определённой последовательности не только из-за больших пусковых токов, а ещё и для того, чтобы не раскачивалась стойка от раскручивающихся дисков. Другой пример: серверы организованы в коридор – стойки стоят напротив друг друга и серверы выдувают горячий воздух внутрь получившегося коридора, тогда и включать их надо пáрами, чтобы не перегреть ещё не включённые серверы.
Многое зависит от того, как спроектирован конкретный суперкомпьютер, поэтому хорошо изучите его структуру и процедуру старта. Конечно, эти и другие проблемы касаются и больших офисов, но в кластере они возрастают многократно. Все эти проблемы решаемы с той или иной степенью эффективности, но нередко методы их решения отличаются от «офисных». Во многом всё зависит от оборудования – при планировании суперкомпьютера очень важно помнить о пиковых нагрузках. Тут они – серая повседневность, поэтому изначально надо закладывать решения, позволяющие их выдерживать.
Кроме чисто аппаратных решений важны и программные: если один ключевой сервис поставить даже на супермощный сервер, то он всё равно может не справиться с нагрузкой, и, возможно, надо подумать о дублировании или разделении нагрузки. Если же при планировании по какой-то причине не удалось всё учесть и под нашей опекой оказался кластер с «бутылочным горлышком», то нужно суметь найти способ расширить или совсем ликвидировать это горлышко, например, заменив часть оборудования и/или программного обеспечения, но это обычно непросто.
Как мы увидим далее, аспектов управления вычислительным комплексом масштаба вычислительного кластера очень много. Тут и развёртывание системы, и обновление ПО, и контроль учётных записей, удалённого доступа, управление доступом и заданиями, мониторинг, резервное копирование и многое другое. Каждая из этих задач по отдельности решается, а как – мы покажем в этой книге. Однако объём действий, совершаемый администратором при массовых операциях, таких, как заведение групп пользователей с присвоением им специфических прав, изменения в настройках сетевых устройств или узлов, становится весьма внушительным.
Тут на помощь вам придут знания скриптовых языков – большинство таких действий автоматизируется скриптами. Но, к сожалению, не все действия можно выполнить набором скриптов. В нелёгкие будни системный администратор большого вычислительного комплекса всё чаще задумывается об удобной «консоли», в которой можно сделать всё, что требуется, не запуская лишних программ, скриптов, не копируя промежуточных файлов и текста с экрана терминала. Особенно часто такие мысли возникают при виде продуктов типа HP OpenView или Zenoss. «Вот она – панацея!» – так и хочется воскликнуть. И правда, такие продукты нацелены на решение очень похожих задач. Они сами инвентаризируют оборудование, ведут учёт пользователей и ПО, делают массу автоматизированных действий… Более того, их действительно можно (а если есть возможность, то и нужно) приспособить для решения части ваших задач.
Увы, лишь части. Подобные продукты, как коммерческие, так и свободные, нацелены именно на похожие, пересекающиеся с нашими, но всё же другие задачи. Заставить их делать то, чего они не умеют, но что нужно нам, иногда можно, но это требует колоссальных затрат – людских, финансовых, времени… А как только конфигурация вашего суперкомпьютера поменяется, всё это придётся делать заново. По нашему личному опыту и опыту многих администраторов суперкомпьютеров, с которыми мы общались, универсальных решений нет. К сожалению, создание таких инструментов востребовано только узким кругом администраторов, при этом оно дорого в разработке и поддержке. Именно поэтому мы хотим обратить ваше внимание на важность системного подхода ко всем учётным и организационным действиям с вычислительным комплексом. Однако это не значит, что нужно выбирать как можно более интегрированные решения. Это значит, что все действия должны быть хорошо описаны – не для того, чтобы не забыть, а для того, чтобы видеть картину в целом и в изменившихся условиях быстро адаптировать к ним устоявшиеся процессы.
Старайтесь использовать гибкие и расширяемые инструменты. И не забывайте учиться новому, применять адекватные (а не только самые модные) технологии к решению всего комплекса задач администрирования суперкомпьютера!
Суперкомпьютер очень похож на «много-много обычных серверов», но в то же время особенностей работы с ним намного больше, чем с множеством серверов. Очень многие серверные технологии тут используются для решения стандартных задач, но не для всех они применимы. Кроме того, есть множество специфичных задач и технологий, применяемых только в области супервычислений.
HPC, beowulf, supercomputer.