Без учета особенностей преодоления энергетических ограничений и барьера, вызванного ростом разрыва между быстродействием логических элементов и элементов памяти, дальнейшее увеличение производительности суперкомпьютерных систем вообще и комплексов интенсивной обработки данных, включающих эффективное выполнение нерегулярной работы с памятью и обработку мощных поступающих потоков данных, невозможно.
Виктор Корнеев
В результате целенаправленных усилий компаний Cray и IBM по учету специфики организации параллельных вычислений и имеющихся ограничений, возникающих при преодолении планки реальной производительности в 1 PFLOPS, были созданы суперкомпьютеры IBM Roadrunner и Cray XT4, Cray XT5h, Cray XMT, формирующие передовой край современной суперкомпьютерной индустрии. Однако данные системы — лишь этап для перехода к созданию еще более производительных систем с новыми архитектурами. Каковы дальнейшие пути развития индустрии? Для ответа на этот вопрос посмотрим на основные направления развития суперкомпьютеров и пути совершенствования высокопроизводительных архитектур в направлении повышения эффективности исполнения параллельных программ с интенсивным обращением к памяти по адресам, определяемым в ходе их выполнения.
Направления развития суперкомпьютерных систем
Структуры нынешних суперкомпьютеров образованы сетью узлов, построенной на базе либо коммерчески доступных коммуникационных технологий, например InfiniBand в IBM Roadrunner, либо на фирменной технологии Seastar, как в суперкомпьютерах Cray. Кроме кристалла Seastar с пропускной способностью 6,7 Гбайт/с имеются SeaStar2 с пропускной способностью 7,6 Гбайт/с и SeaStar2+ с 9,6 Гбайт/с и коррекцией ошибок, сокращающей трафик повторной передачи искаженных данных.
Другим направлением развития суперкомпьютеров является использование узлов с сопроцессорами, представленными кристаллами различной архитектуры: SIMD и обработка в памяти в IBM Roadrunner; векторно-конвейерная в Cray X2; мультитредовая в Сray Threadstorm и Cray XMT; FPGA в Cray XR1 и Cray XT4. (Следует отметить, что Cray X2 и Сray Threadstorm — это разработанные в Cray заказные схемы для параллельной обработки.)
Оба направления отражают известный подход — для построения параллельной системы следует использовать наиболее высокопроизводительные узлы и коммуникационную сеть с максимальной пропускной способностью и минимальной задержкой.
Следующее направление состоит в объединении в одной коммуникационной среде подсистем с узлами различной архитектуры, как в Cray XT5h, это служит констатацией того, что различные приложения и их части с разной степенью эффективности исполняются на узлах разных архитектур.
И наконец, в современных суперкомпьютерах построение распределенной разделяемой памяти большого объема осуществляется путем объединения коммуникационной сетью локальных блоков памяти узлов суперкомпьютера. При этом с целью снижения трафика в кэш-памяти узлов допускается кэширование только данных из локального блока памяти.
Перспективы
Анализ ретроспективы развития микроэлектроники показывает, что, как только появляется возможность, в кристалле реализуется вся функциональность материнских плат и блоков, состоящих из совокупности плат, за исключением, пожалуй, памяти большого объема. Поэтому с большой уверенностью можно прогнозировать развитие суперкомпьютеров, следуя эволюционному пути совершенствования микропроцессорных кристаллов и архитектур суперкомпьютеров.
В ближайшей перспективе следует ожидать применения в суперкомпьютерах многоядерных микропроцессорных кристаллов со встроенными контроллерами памяти и каналами «точка-точка», такими как HyperTransport в AMD Barcelona и QuickPath в Intel Nehalem. Это увеличит производительность и коммуникационные возможности по доступу к локальной и удаленной памяти.
Существенно многоядерные кристаллы — с 64 ядрами и более — могут быть использованы как в качестве универсальных процессоров суперкомпьютеров, так и как сопроцессоры, ориентированные на реализацию потоковых вычислений. К примеру, кристалл Tile 64 может быть применен как в том, так и в другом качестве.
Следует ожидать, что в ядра многоядерных кристаллов будет введена векторная обработка и мультитредовость, а также элементы программируемой логики, наряду с уже присутствующей сейчас SIMD-обработкой. Иными словами, функциональность ядер приобретет функциональность узлов сегодняшних суперкомпьютеров.
Коммуникационный кристалл YARC демонстрирует возможность создания кристаллов с большим числом портов высокой пропускной способности. Нет сомнений, что в существенно многоядерный кристалл могут быть внедрены сериализаторы-десериализаторы, обеспечивающие высокую бодовую скорость при малой разрядности портов (выводов кристалла, образующих канал). Узлы с такого рода коммуникационными возможностями могут быть объединены в суперкомпьютеры с различными топологиями для создания сетей с требуемой проблемной ориентацией: многомерные кубы, булевские гиперкубы высокой размерности, сложенные сети Клоса и другие.
Мультиядерные кристаллы
Развитие архитектур мультиядерных кристаллов повторяет эволюционный путь создания вычислительных систем. Уже достаточно давно установлено, что вместо коммутаторов с временным разделением (шин) для получения высокой пропускной способности следует применять коммутаторы с пространственным разделением и каналы «точка-точка». Однако в четырехъядерном кристалле Intel Clovertown, функционирующем на тактовых частотах 2-3 ГГц, применены два уровня шин для объединения процессорных ядер в мультипроцессор SMP-архитектуры. На первом уровне два ядра образуют SMP с общей кэш-памятью второго уровня, на втором — эти SMP объединяются шиной FSB. При образовании восьмиядерного SMP на материнской плате также применяется шинная структура. Четырехъядерный процессор AMD Barcelona также имеет SMP-архитектуру на базе шины, но в нем реализован контроллер памяти и каналы HyperTransport, позволяющие создать на материнской плате распределенную разделяемую память на базе коммуникационной сети с каналами «точка-точка», образованной каналами HyperTransport.
Компания Intel представила архитектуру следующего поколения Nehalem мультиядерных кристаллов, содержащих до восьми двухтредовых ядер. С архитектурной точки зрения Nehalem подобен AMD Barcelona с той разницей, что в нем использован канал QuickPath Interconnect. Как HyperTransport, так и QPI, судя по имеющимся публикациям, допускают образование распределенной разделяемой памяти только на материнской плате. Поэтому при построении систем из этих кристаллов в качестве интерфейсов должен, по-видимому, использоваться PCI Express xN.
Сети многопроцессорных систем, формируемых из однокристальных процессоров, и сети процессорных ядер, размещенных на одном кристалле, имеют разный набор ограничений пропускной способности. В первом случае в качестве ограничений выступают число выводов кристалла, ограничивающее ширину линий, а также энергетические затраты, требуемые приемопередатчиками и линиями связи. Во втором случае ограничений на ширину линий нет, равно как нет больших энергетических затрат в линиях, но возникают технологические ограничения разводки линий, особенно широких линий, по кристаллу. Поэтому в накристальных сетях важным представляется допустимое число уровней металлизации для разводки проводников в разных слоях и выбор топологии межпроцессорных связей, зависящий также от количества объединяемых процессоров. При малом числе процессоров возможно использование кроссбар-коммутаторов, как в Sun UltraSPARC T1, или кольцевого канала, примененного в IBM Cell и планируемого в Intel Larrabee. Однако в масштабируемых сетях, рассчитанных на объединение сотен процессоров, должна использоваться другая топология, например двухмерная решетка. Эта топология использована в мультиядерном кристалле Tilera и экспериментальном кристалле Intel TRC.
Компания Tilera в августе 2007 года выпустила процессор TIle64, в основе идеологии которого лежит исследовательский проект RAW Массачусетского технологического института. Кристалл содержит 8х8 процессорных ядер, четыре 64-разрядных контроллера памяти DDR2/800 МГц и совокупность периферийных контроллеров, реализующих в том числе два дуплексных интерфейса PCI-Express х4, два дуплексных порта XAUI и два интерфейса Gigabit Ethernet. Суммарная пропускная способность интерфейсов памяти кристалла находится на уровне 200 Гбит/с, а подсистемы ввода-вывода — 40 Гбит/с. При тактовой частоте 1 ГГц производительность кристалла Tile64 оценивается в 0,192 х 1012 32-разрядных операций в секунду, или 0,256 х 1012 при 16-разрядных операциях, или 0,5 х 1012 8-разрядных операций. Для именования процессорных ядер используется термин tile (в английском языке этим словом обозначают объекты, плотно покрывающие некоторую площадь, например кафель, черепица и т.д.). Процессорное ядро кристалла Tile64 включает собственно процессор, многоуровневую кэш-память, а также коммуникационный узел сети iMesh.
Каждый процессор имеет собственную таблицу трансляции виртуальных адресов памяти. Процессор имеет архитектуру VLIW, допуская выполнение в одном такте трех команд, аналогичных RISC-командам процессоров с архитектурой MIPS. Каждое процессорное ядро кристалла может функционировать под собственным экземпляром операционной системы, и все ядра могут управляться одним экземпляром ОС, образуя 64-процессорный SMP.
В отличие от традиционного подхода, при котором процессорные ядра объединяются одной физической сетью, разделяемой затем многими логическими сетями, в Tile64, исходя из специфики создания накристальных сетей, ядра объединены пятью физическими сетями, в совокупности образующими сеть iMesh. Каждая из этих пяти сетей ориентирована на выполнение общесистемных или прикладных функций. Выбор именно этого числа сетей и функций, ими реализуемых, основан на результатах проекта RAW chip. Каждый канал каждой сети состоит из двух противоположно направленных каналов шириной 32 бит, что позволяет одновременно передавать данные в обоих направлениях.
Введение специализированных сетей позволяет увеличить быстродействие за счет исключения тэгов данных, определяющих принадлежность данных логической сети, устранения мультиплексирования и демультиплексирования передаваемых данных разных логических сетей, а также уменьшает объем необходимых приемных буферов. Кроме того, проектирование и функционирование пяти простых сетей проще и надежнее, чем проектирование одной, реализующей все их функции.
Две аппаратно управляемые сети MDN и TDN из состава iMesh служат для организации работы с многоуровневой разделяемой памятью кристалла. Другие три сети управляются программно и предназначены для обменов между процессорными ядрами в ходе исполнения программ и осуществления операций ввода/вывода. Это пользовательская сеть с динамической маршрутизацией UDN, сеть ввода/вывода с динамической маршрутизацией IDN, а также пользовательская сеть STN со статической маршрутизацией. Сеть UDN с динамической маршрутизацией применяется для передачи пакетов, без обращения к ОС, между процессами или тредами пользовательской программы, протекающими в разных ядрах. Реализация ядра предусматривает выработку быстрого пользовательского прерывания для извещения треда о поступлении данных. Сеть STN со статической маршрутизацией, используя дополнительный специальный программируемый сетевой процессор, передает поток данных по предварительно установленным путям, не используя пакетизацию передаваемых данных. Это маршрутизация типа «коммутация каналов». Сеть IDN с динамической маршрутизацией служит для обеспечения доступа процессорных ядер к внешним устройствам. Кроме того, по этой сети обслуживаются коммуникации ОС и гипервизора.
В кристалле Tile64 предусмотрен механизм Multicore Hardwall блокирования каналов сетей UDN, STN, IDN с целью разбиения кристалла на подсистемы ядер, в каждой из которых протекают свои процессы, не взаимодействующие с процессами других подсистем. Каналы сетей MDN и TDN не блокируются, так как для устранения взаимовлияния достаточно механизмов защиты памяти на уровне таблиц трансляции виртуальных адресов. При поступлении пакета в заблокированный канал вырабатывается прерывание, обрабатываемое гипервизором.
Tile64 поддерживает ОС Linux, имеются средcтва разработки MDE (Multicore Development Environment), включающие интегрированную среду разработки на базе Eclipse, компилятор Си и инструментарий для отладки программ. Для создания программ можно применять коммуникационную библиотеку iLib, содержащую средства как для организации каналов для передачи потоков данных между процессами и тредами, так и для обмена сообщениями в стиле MPI. Кроме того, возможно программирование на базе модели общей памяти.
Основной целью проекта Intel Terascale было исследование возможности создания накристальных сетей и управление энергопотреблением. Кристалл TRC содержит решетку 8х10 процессорных ядер. Каналы между ядрами устойчивы к фазовым сдвигам их тактовых сигналов. Канал между двумя ядрами поддерживает функционирование двух логических каналов (канал 0 и канал 1). Канал 0 обычно используется для передачи коротких сообщений, содержащих команды, а канал 1 — для передачи длинных сообщений с данными. Это предотвращает возможность задержки передачи команд.
Сообщения при передаче по решетке пакетизируются. В свою очередь, пакеты разбиваются на «флиты» (flit — от flow control unit), неделимые блоки данных, состоящие из 32 бит данных и 6 управляющих битов, задающих в том числе начальный и последний флит пакета. В заголовке пакета содержится маршрут его передачи в виде последовательности выходных направлений коммутатора при прохождении каждого транзитного ядра, вплоть до достижения ядра назначения. Для передачи пакетов используется пространственно упорядоченная червячная маршрутизация. Пропускная способность пятипортового неблокируемого коммутатора ядра составляет 100 Гбайт/с.
Процессор позволяет получать четыре результата с плавающей запятой за такт, а при использовании VLIW-архитектуры с длиной команды 96 бит — до восьми операций за такт. Система команд Intel Terascale очень ограничена: нет целочисленной арифметики, нет битовых операций, нет условных переходов, кроме не допускающей вложенности команды организации цикла, а также возможности только односторонней анонимной коммуникации между ядрами. Максимум производительности TRC равен 1,8 TFLOPS при частоте 5,6 ГГц.
Повышение эффективности использования ядер
При исполнении программ каждое процессорное ядро узла суперкомпьютера обращается к распределенной разделяемой памяти. Так как дальнейшее выполнение программы возможно только после получения операнда из памяти, в случае чтения, или подтверждения завершения записи перед выполнением последующего чтения, то в процессорных ядрах для сокращения простоев, связанных с ожиданием операндов или синхронизацией, необходимо вводить механизм, уменьшающий эти простои. Данная проблема не нова и обусловлена возрастающим разрывом в быстродействии логических элементов и элементов памяти, однако в параллельных системах она приобретает дополнительную остроту в связи с тем, что пропускная способность коммуникационной среды много ниже пропускной способности доступа к локальному блоку памяти. Даже при потоковом представлении программ (когда операнды передаются с выхода выработавшего их процессорного ядра на вход одного или нескольких ядер в соответствии с потоковым графом программы, что снижает количество доступов к памяти) при программировании реальных задач, как правило, не удается избежать обращений к памяти по произвольным, вычисленным в ходе исполнения программы, адресам. Чтобы понять, какой должна быть архитектура процессорного ядра, рассмотрим, какие механизмы существуют для снижения потерь производительности из-за простоя процессора в ожидании данных или выполнения синхронизации.
Первая попытка снижения потерь производительности из-за простоя процессора была предпринята в рамках суперскалярной архитектуры за счет введения внутрикристальной многоуровневой кэш-памяти для сокращения количества обращений к памяти, а также станций резервирования, в которых команды ожидали поступления операндов, и других приемов. Однако количество команд, образующих окно исполнения суперскалярного процессора, ограничено и дальнейшее наращивание объемов кэш-памяти и количества запускаемых на выполнение команд не дает прироста производительности, пропорционального затрачиваемым ресурсам и энергии. Невозможность автоматически аппаратными средствами исключить простои процессора привела к попытке использования архитектуры с длинным командным словом, в которой загрузка процессора возложена на компилятор и программиста. Однако эта архитектура также не дала удовлетворительного результата. Поэтому сегодня развивается другой подход, основанный на поддержке протекания «легких» тредов. В программе выявляется как можно больше даже очень небольших последовательностей команд, оформляемых как легкие треды и асинхронно запускаемых на исполнение при наличии простаивающих ресурсов процессора.
Как пример реализации этого подхода разработана библиотека для порождения и управления легкими тредами, названными qthread, в рамках POSIX-тредов процессов Unix. На уровне qthread API для поддержки локальности легких тредов в распределенной разделяемой памяти вводятся «смотрители», под управлением которых порождаются и протекают треды в одном и том же со смотрителем сегменте памяти. В библиотеке qthread для синхронизации легких тредов предлагается API, подобный используемому в Tera MTA. Этот подход к заданию синхронизации легких тредов служит альтернативой используемому при синхронизации POSIX-тредов. Широко применяемый подход к реализации синхронизации на базе «замков» (переменных, чаще всего битов, значения которых проверяются и изменяются неделимыми последовательностями команд) представляется малопродуктивным при синхронизации динамически порождаемых тредов, в том числе легких тредов, из-за больших задержек. Поэтому предлагается синхронизация на базе расширения каждого слова памяти дополнительным FE битом (full/empty), значение которого full указывает, что слово памяти имеет содержимое, в противовес отсутствию содержимого при значении empty.
Рисунок иллюстрирует эффективность использования библиотеки qthread при выполнении алгоритма быстрой сортировки quicksort по сравнению с реализацией этого алгоритма средствами традиционной библиотеки libc qsort (). В эксперименте использовался массив из миллиарда 64-разрядных чисел в формате с плавающей запятой на 48-процессорной системе SGI Altix SMP с процессорами Itanium/1,5 ГГц.
Основой синхронизации и коммуникации между тредами служат команды writeef, readfe, readff и writeff. Последние два символа в командах записи write и чтения read служат параметрами. Первый символ задает значение бита FE, при котором возможно выполнение команды, а второй определяет значение бита FE, устанавливаемое после выполнения команды записи или чтения. Например, команда writeff может быть исполнена только в том случае, если значение бита FE слова памяти, в которое должна быть произведена запись, равно full, и после записи значение бита FE этого слова получит значение full.
Не вызывает сомнения необходимость подготовки программ для суперкомпьютеров с многоядерными узлами, используя механизм легких тредов. При этом надо различать синхронизацию и управление процессами и тредами на аппаратно-программном уровне реализации процессора, в противовес API, предоставляемому программисту для формулирования алгоритма вычислений. Поэтому механизм легких тредов может быть введен в процессорные ядра как аппаратно, так и программно, например, на базе библиотеки qthread. Легкие треды состоят из небольшого числа команд и требуют небольшого объема стека для сохранения своего состояния — контекста треда. В прикладных программах могут быть приняты соглашения о сохраняемых переменных, которые поддерживаются библиотекой, используемой для порождения в программе легких тредов, а также их синхронизации.
Исследования в области архитектуры процессоров с памятью, слова которой расширены битом FE, привели к многообещающим результатам. Например, развивается архитектурный подход использования бита FE каждого слова памяти для реализации функций управления процессором, включая отладочные режимы, синхропримитивы и так далее. Подход основан на том, что при состоянии «пусто» бита FE биты этой ячейки памяти трактуются процессором как управляющая информация. Поэтому, установив в любой ячейке памяти, к которой идет обращение в программе, значение бита FE «пусто», можно вызвать требуемый обработчик ситуации.
Суперкомпьютер будущего
Не вызывает сомнения, что суперкомпьютер на базе существенно многоядерных кристаллов будет содержать миллионы процессорных ядер, однако для того, чтобы достичь этой производительности на реальных задачах, необходима также разделяемая всеми процессорными ядрами память с поддержкой малого времени доступа для получения высокой производительности на программах, обрабатывающих большие потоки данных с интенсивным обращением к разделяемой памяти по вычисляемым адресам.
Для реализации разделяемой памяти идеальным узлом будет конструктивный элемент, содержащий локальный блок памяти и существенно многоядерный кристалл со встроенными контроллерами памяти и высокоскоростными портами. Конечно, возможны и другие структуры узла, а именно: отдельный коммуникационный кристалл для одного или нескольких кристаллов с процессорными ядрами, но принципиально суперкомпьютер будет иметь распределенные по узлам локальные блоки разделяемой памяти с введенным в каждое слово памяти битом FE. Для обеспечения высокой пропускной способности встроенные в кристалл контроллеры памяти должны поддерживать высокую степень расслоения локального блока памяти, а процессорные ядра — допускать большое число незавершенных обращений к памяти. На уровне ОС суперкомпьютера должно программно формироваться глобальное адресное пространство разделяемой памяти, состоящей из блоков локальных памятей узлов.
Многоуровневую кэш-память существенно многоядерного кристалла и адресацию разделяемой памяти разумно реализовать по примеру процессора Tile64, что обусловлено минимизацией как количества обращений к внекристальной памяти, так и времени доступа к ней. Однако возможна и другая организации памяти процессорных ядер, например подобная той, что применена в кристалле Cell.
Процессорные ядра должны быть мультитредовыми и иметь команды writeef, readfe, readff и writeff для поддержки синхронизации и коммуникации между легкими тредами, POSIX- тредами и процессами исполняемых программ. Это позволит выдавать максимально возможное в исполняемой программе количество обращений к памяти, генерируемых легкими тредами, и параллельно выполнять эти доступы в расслоенной памяти.
Кроме того, необходимо минимизировать количество обращений к памяти. Это возможно, например, при выборе алгоритма решения задачи, допускающего создание потоковой программы. В этом случае прикладная программа подготавливается пользователем исходно как потоковая или преобразуется в таковую компилятором. Межъядерные потоки программируются исходя из параметрического описания графов связей подсистем, на которых эти программы способны выполняться. Для выполнения прикладных программ операционная система суперкомпьютера должна формировать связную подсистему процессорных ядер с требуемым программой типом графа межъядерных связей и алгоритмом нумерации ядер [8].
При потоковом представлении программы значительная доля обрабатываемых операндов будет передаваться между ядрами по линиям, существенно снижая количество обращений к памяти. Уже имеются примеры создания потоковых программ для ряда задач линейной алгебры и математической физики с ускорением параллельных вычислений, прямо пропорциональным количеству используемых процессорных ядер при соответствующем размере задачи. При использовании 105 кристаллов, подобных Tile 64 и Intel TRC с производительностью на уровне 1 TFLOPS, производительность суперкомпьютера достигнет 100 PFLOPS.
Виктор Корнеев (korv@rdi-kvant.ru) — сотрудник НИИ «Квант» (Москва).
Программная настраиваемость аппаратной структуры http://www.osp.ru/os/2007/10/4705462