Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Суперкомпьютеры и системы. Мультипроцессоры. Учебное пособие
.pdf
сти – идеально соответствовала принципам архитектуры ОКМД. Поэтому в видеоакселераторах стали реализовываться специализированные
потоковые процессоры, работавшие вначале по фиксированным зашитым алгоритмам обработки графической информации. Затем с целью
обеспечения большей степени гибкости в видеоакселераторах были реализованы возможности загрузки программ обработки из центрального
процессора. До середины 2000-х годов эти программы разрабатывались
на узкоспециализированных языках обработки графической информации. При этом производительность видеоакселераторов быстро росла и
начала превосходить (и существенно) производительность центральных
процессоров, правда только на ограниченном круге задач.
И, наконец, в 2006 году компания NVIDIA преодолела устоявшийся к тому моменту психологический барьер и представила технологию
обработки неграфической информации на графическом процессоре под
названием CUDA – Compute Unified Device Architecture.
Технология CUDA основывается на аппаратной ОКМД-структуре,
изображенной на рис. 4.2, и представляет собой синтаксическое расширение языков С/С++ при помощи дополнительных спецификаторов
(ключевых слов) переменных и функций, а также библиотек функций и
механизма запуска ядер.
Графический процессор обычно содержит несколько (от единиц до
десятков в зависимости от модели устройства) вычислителей – мультипроцессоров в терминологии NVIDIA . Мультипроцессоры работают
под управлением аппаратно реализованного планировщика блоков потоков. На рис. 4.3 для примера показано размещение основных элементов графического процессора NVIDIA с микроархитектурой Fermi.
Этой микроархитектуре предшествовала Tesla, далее появились Kepler,
Maxwell и Volta. Переход от одной микроархитектуры к другой сопровождается увеличением производительности чипа и уменьшением относительных энергозатрат на каждый выполняемый гига- (или тера-)
флоп.
Мультипроцессор архитектуры Fermi содержит следующее:
планировщик пучков потоков (варпов в терминологии NVIDIA );
кэш-память для хранения инструкций исполняемого ядра;
устройство управления, выбирающее и декодирующее инструкции;
набор арифметико-логических устройств (потоковых процессо-
ров в терминологии NVIDIA , их количество также зависит от модели
устройства и колеблется от 16 до 192) для обработки целых чисел и
чисел с плавающей запятой одинарной точности в режиме ОКМД;
51

Рис. 4.2. ОКМД-структура графического процессора NVIDIA
Рис. 4.3. Основные элементы графического процессора NVIDIA
52

несколько арифметико-логических устройств для обработки чи-
сел с плавающей запятой с двойной точностью;
регистровый файл (быстрая память на кристалле, распределяе-
мая между потоками блока);
разделяемую (доступную всем потокам блока) быструю память.
Кроме совокупности мультипроцессоров кристалл графического
процессора содержит общие для них элементы:
уже упоминавшийся планировщик блоков потоков;
несколько контроллеров глобальной памяти устройства, находя-
щейся вне чипа и обладающей существенно большим объемом, но значительно меньшим (в 300–500 раз) быстродействием по сравнению с
внутрикристалльной памятью;
L2-кэши глобальной (отсутствуют в архитектуре Tesla), текстур-
ной и константной памяти.
Рис. 4.4. Микроархитектура ядра Cayman компании AMD
53

Видеоадаптеры основного конкурента фирмы NVIDIA – компании AMD – развивались в аналогичном направлении, что также привело к созданию высокопроизводительных графических процессоров.
На рис. 4.4 показана укрупненная структура ядра микроархитектуры
Cayman, используемой в нескольких моделях высокопроизводительных графических процессоров серий Radeon HD 69хх и FirePro. Компоненту гетерогенной системы Compute Unit (мультипроцессору в
терминологии NVIDIA) здесь соответствует SIMD Engine, содержащий большое количество (320…384) потоковых процессоров.
Совокупность ОКМД Engine управляется командным процессором
(Command Processor), генератором потоков управления (Thread
Generator) и устройством их распределения (Ultra-Threaded Dispatch
Processor). В отличие от планировщиков блоков и ворпов, управляющих мультипроцессорами как единицами вычислительного контекста в
графических процессорах фирмы NVIDIA, эти компоненты чипа
Cayman способны асинхронно распределять между потоковыми процессорами всю совокупность задач, сформированных драйвером для
графического процессора. Затраты времени на переключения потоковых процессоров даже между различными ядрами в этой технологии
оказываются незначительными.
Выборку данных для потоковых процессоров выполняет Fetch Unit,
связанный с основной памятью через кэши L1 и L2 объемом 8 кБ и
128 кБ соответственно. Локальная память Local Data Store объемом
32 килобайта соответствует регистровому файлу в устройствах NVidia.
4.2. ВЫЧИСЛИТЕЛЬНЫЕ АКСЕЛЕРАТОРЫ
Вычислительные акселераторы – это специализированные параллельные процессоры, изначально ориентированные на обеспечение
высокой производительности при относительно небольших аппаратных затратах. К вычислительным акселераторам относится Intel Xeon
Phi – специальный ускоритель для научных расчетов, имеющий терафлопсную производительность (один триллион операций с плавающей
точкой в секунду). В отличие от графических процессоров (NVIDIA
GPGPU, AMD Radeon и др), Intel Xeon Phi основан на архитектуре
процессора x86, его структура изображена на рис. 4.5.
Чип содержит:
высокопроизводительную широкую кольцевую шину для связи
всех компонентов, находящихся внутри чипа;
54

Рис. 4.5. Структура вычислительного акселератора Intel Xeon Phi
большое количество (от 60) процессорных ядер, каждое из кото-
рых имеет собственный когерентный L2 кэш;
восемь контроллеров GDDR MC, которые обслуживают 16 кана-
лов памяти типа GDDR5;
отдельный компонент реализует клиентскую логику PCI Express
для подключения акселератора к центральному процессору.
Intel Xeon Phi выполнен в виде платы расширения стандарта PCI
Express на основе многоядерного процессорного чипа (от 60 ядер x86)
с памятью стандарта GDDR5. Плата имеет разъем PCI Express x16, ее
энергопотребление достигает 300 Вт. Каждое ядро содержит когерентный кэш второго уровня объемом 512 кБ и имеет доступ к своей собственной оперативной памяти, объем которой варьируется от модели к
модели.
Xeon Phi – реализация архитектуры Intel MIC (Many Inegrated Core
или «большое количество ядер в одной микросхеме»), позволяющей использовать стандартный исходный код на языках C, C++ и FORTRAN и
компилировать его для исполнения как на Xeon Phi, так и на любых
компьютерах с процессорами Intel Xeon.
55

4.3. ПРОБЛЕМЫ ПРОГРАММИРОВАНИЯ
ГРАФИЧЕСКИХ ПРОЦЕССОРОВ
И ВЫЧИСЛИТЕЛЬНЫХ АКСЕЛЕРАТОРОВ
Использование графических процессоров и вычислительных акселераторов в составе и суперкомпьютеров, и обычных персональных компьютеров сопряжено с возникновением ряда проблем и трудностей [15].
Они обусловлены принципиально иным соотношением последовательного / параллельного в вычислениях, чем в любых ранее существовавших
параллельных системах. Возможность запуска десятков и сотен миллионов параллельных потоков вычислений без необходимости непрерывно
координировать их работу радикально изменяют сами принципы программирования. Неоднородность вычислительных средств, содержащих
центральный многоядерный процессор и акселератор на основе ОКМДпринципов, приводит к необходимости решения задачи распределения
нагрузки на этапе разработки алгоритма решения прикладной задачи. Постоянно протекающие процессы интеграции разнотипных компьютерных
компонентов в состав чипов центральных процессоров требуют тщательного анализа существующих тенденций при выборе направлений
развития средств программирования акселераторов.
Первая созданная для поддержки неграфических высилений на графических процессорах технология программирования CUDA является
проприетарным продуктом и может быть использована только для
устройств NVIDIA. Cложность написания качественного кода на CUDAрасширении языков C и C++ привела к созданию ряда других технологий программирования акселераторов, в том числе OpenCL, C++ AMP и
OpenACC.
OpenCL является непроприетарным двойником CUDA и пользуется
поддержкой многих крупных компаний. Он не ограничен только чипами
NVIDIA, но поддерживает графические процессоры AMD, многоядерные CPU, Intel Xeon Phi, цифровые сигнальные процессоры и программируемые логические матрицы, что делает его переносимым. Однако,
так же как и CUDA, он очень низкоуровневый: требует от программиста
непосредственного управления перемещением данных между центральным и графическим процессорами, явного определения мест хранения
переменных в иерархии памяти и ручной реализации параллелизма в
коде.
Технология C++ Accelerated Massive Parallelism (C++ AMP) имеет
более высокий уровень. Она позволяет описывать параллельные алго-
56

ритмы уже на самом С++ и скрывает весь низкоуровневый код от программиста. Оператор «for each» инкапсулирует параллельный код.
Технология C++ AMP привязана к операционным системам Windows;
пока ещё не поддерживает, как это умеет OpenCL, ускорители разных
архитектур и имеет слишком большие накладные расходы на запуск
приложения.
OpenACC – это еще более высокоуровневый подход к программированию ускорителей, который позволяет программистам снабдить код директивами, сообщив тем самым компилятору, какие части кода требуется
ускорить, выгружая их в графический процессор. Идея схожа с тем, как
OpenMP используется для распараллеливания CPU-программ. Предпринимаются усилия к объединению этих двух подходов. OpenACC находится на этапе созревания и в настоящее время поддерживается только немногими компиляторами.
Чтобы понять, как в дальнейшем будет развиваться область программирования аппаратных ускорителей, стоит изучить, как подобный
процесс протекал в прошлом с другими аппаратными ускорителями.
К примеру, микропроцессоры ранних персональных компьютеров «не
умели» выполнять операции с плавающей точкой. В составе таких компьютеров обычно имелся дополнительный компонент – сопроцессор,
выполняющий вычисления с плавающей точкой. Позже он был объединен на одном кристалле с центральным процессором и сейчас является
его неотъемлемой частью. Процессор и сопроцессор имеют лишь разные
регистры и арифметико-логические устройства. Более поздние ОКМДрасширения процессоров (MMX, SSE, AltiVec и AVX) не выпускались в
виде отдельных чипов, но сейчас они полностью интегрированы в процессорные чипы. Точно так же, как и инструкции с плавающей точкой,
ОКМД-инструкции выполняются на отдельных АЛУ и с использованием собственных регистров.
Удивительно, но два этих типа инструкций существенно различаются, с точки зрения программиста. Вещественные типы и операции с
ними были давно стандартизированы (IEEE 754) и сегодня используются повсеместно. Они доступны в высокоуровневых языках программирования через обычные арифметические операции и встроенные
вещественные типы данных: 32 бита для вещественных чисел одинарной точности и 64 бита для двойной точности. Однако не существует
никаких стандартов для ОКМД-инструкций, и само их наличие в процессоре, как правило, скрыто от программиста. Использование ОКМДинструкций для ускорения вычислений путем векторизации по умол-
57

чанию делегировано компиляторам, а их разработчики далеко не всегда используют эти возможности. Программисты, желающие явно использовать ОКМД-инструкции, должны обращаться к компилятору
при помощи специальных некроссплатформенных макросов.
В силу того что высокая производительность GPU и MIC ускорителей обусловлена их ОКМД-природой, весьма вероятно, что их развитие
пойдет путем предыдущих ОКМД-расширителей. Еще одно сходство с
ОКМД – ключевая особенность технологии CUDA, сделавшая ее
успешной. Она состоит в том, что CUDA скрывает ОКМД-сущность,
характерную для графических процессоров, и позволяет программисту
мыслить в терминах потоков, оперирующих скалярными данными, в то
время как графический процессор работает в терминах варпов (warp),
оперирующих векторами. Поэтому вполне вероятно, что ОКМД-ускорители в конечном итоге тоже будут перенесены на кристалл процессора.
Такие примеры уже известны. Некоторые ускорители уже были
совмещены на кристалле с традиционными процессорами – это AMD
APU (используется в Xbox One), процессоры Intel с интегрированной
HD-графикой и Tegra SoC от NVIDIA. Однако ОКМД-ускорители
останутся, вероятно, отдельно программируемым компонентом просто
потому, что трудно объединить их с традиционным процессорным ядром до такой же степени, как это было сделано с математическим сопроцессором и с ОКМД-расширениями. В конце концов ОКМД-ускорители именно потому такие быстрые, параллельные и энергоэффективные, что построены на основе отличных от CPU архитектурных решений, таких как некогерентый кэш, совершенно другая реализация конвейера, память GDDR5, на порядок большее количество регистров, легковесная многопоточность. Следовательно, сложность запуска кода на
акселераторах по-прежнему останется. Скорость обмена данными между CPU и ОКМД-акселераторами будет расти, но все-таки останется узким местом.
Необходимость явного управления процессами обмена данными
между устройствами является существенным источником ошибок и
трудностей. Для небольших алгоритмов часто бывает, что приходится
писать больше кода для того, чтобы организовать обмен данными, чем
для вычислений. Устранение этого недостатка является одним из основных преимуществ высокоуровневых подходов к программированию, таких как C++ AMP и OpenACC. Даже низкоуровневые реализации направлены на решение этой проблемы. К примеру, хорошо отлаженный и унифицированный доступ к памяти – это одно из основных
58

улучшений, которые реализуются в последних версиях CUDA, OpenCL
и аппаратных решениях NVIDIA GPU. И тем не менее для достижения
хорошей производительности обычно требуется помощь программиста
даже в таких высокоуровневых решениях, как OpenACC.
К сожалению, все упрощения, предлагаемые такими подходами,
могут оказаться только частным решением. Учитывая, что будущие
процессоры станут близки к сегодняшним (малым) суперкомпьютерам,
вполне вероятно, что в них будет больше ядер, чем их сможет обслуживать общая память. Весьма вероятно также, что на каждом кристалле будет реализовано несколько кластеров из потоковых ядер, а каждый кластер будет иметь собственную память. Кластеры будут связаны
друг с другом сетью, выполненной на том же кристалле и использующей протокол, подобный MPI. Примером движения в этом направлении могут служить процессоры SW26010, на которых построен китайский суперкомпьютер TaihuLight, рассматриваемый во второй части
пособия. Процессорные чипы будут содержать множество кластеров с
собственной памятью. Каждый кластер будет состоять из многих ядер,
при этом необязательно все ядра будут функционально идентичными.
Каждое многопоточное ядро будет состоять из множества вычислительных звеньев (т. е. функциональных блоков или АЛУ) и каждое вычислительное звено будет выполнять ОКМД-инструкции.
Это поднимает крайне важный вопрос, как программировать такие
устройства. Вполне возможно, что это будет развитием современных
решений для многоядерных CPU, их ОКМД-расширителей и существующих на данный момент акселераторов. Происходит это на трех уровнях:
библиотеки;
инструменты автоматизации;
«сделай сам».
Библиотеки – простейший для прикладного программиста подход,
основанный на вызове функций из библиотек, которая была ранее создана и оптимизирована для ускорителя. Если большинство вычислений программы может быть выполнено путем вызова библиотечных
функций, то применение этого подхода будет вполне оправдано. Уже
сейчас существует большое количество таких библиотек, например,
CuBLAS, CuFFT, CuDNN для графических процессоров NVidia.
В технологиях C++ AMP и OpenACC используется другой подход –
инструменты автоматизации. При таком подходе тяжелая работа по
организации взаимодействия центрального процессора и акселератора
59

перекладывается на компилятор. Качество решения им этой задачи
зависит от качества и сложности существующих программных инструментов и, как было сказано, часто требует вмешательства программиста. Тем не менее большинство программистов могут довольно
быстро достичь хороших результатов, используя этот подход, который
не ограничен только применением предопределенных функций из библиотек.
Наконец, подход «сделай сам» используется в CUDA и OpenCL. Он
дает программисту полный контроль над доступом почти ко всем ресурсам ускорителя. При хорошей реализации результирующий код
обычно превосходит по производительности любой из двух предыдущих. Но это дается путем значительных усилий на изучение языка и
акселератора и написание большого количество дополнительного кода
и обеспечивает больший простор для возможных ошибок. Всяческие
усовершенствования сред разработки и отладки могут смягчить все эти
трудности, но только до определенной степени. А значит, этот подход
полезен в первую очередь для экспертов, т. е. тех специалистов, которые занимаются разработкой методов двух предыдущих подходов.
Поскольку OpenCL предлагает практически все решения, представленные в CUDA, не является проприетарным и поддерживает разные аппаратные решения, эта технология или производные от нее решения, вероятнее всего, станут преобладающими в области программирования вычислительных акселераторов подобно тому, как MPI стал
стандартом де-факто в программировании систем с распределенной
памятью.
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
