- •1.3.2. Прикладная математика и информатика
- •2. Проблемы, связанные с использованием параллельных алгоритмов
- •3. Примеры и описание технологий параллельного программирования
- •3.1. Технологии для разработки параллельных программ для систем с общей и распределенной памятью.
- •3.1.1. Модель передачи сообщений. Mpi.
- •3.2. Технологии разработки параллельных программ для графических процессоров
- •4. Средства анализа технологий параллельного программирования.
- •4.1. Комплексный подход к анализу эффективности программ для параллельных вычислительных систем
- •4.2. Типы анализа производительности
- •5.Анализ производительности технологий mpi и OpenMp
3.2. Технологии разработки параллельных программ для графических процессоров
Рассмотрим технологии CUDA и OpenCL.
3.2.1. CUDA
CUDA – программное обеспечение и аппаратная архитектура параллельных вычислений, благодаря которой возможно значительно повысить производительность вычислений на графических процессорах.
Технология CUDA – это аппаратное и программное обеспечение вычислительной архитектуры, что позволяет обеспечить доступ к набору инструкций графического ускорителя и распоряжаться его памятью в формировании параллельных вычислений. Базой данной технологии является язык программирования С. CUDA дает возможность выполнять алгоритмы осуществимые видеокартах компании Nvidia.
Даже если сложность программирования видеокарт с использованием CUDA довольно велика, она меньше, по сравнению с предшествующими GPGPU. Подобные программы разделяют задачи на несколько мультипроцессоров, что схоже с программированием модели передачи сообщений MPI, но с отличием в том, что данные хранимые в общей памяти не разделяются. В виду того, что программирование CUDA для каждого мультипроцессора схоже с программированием OpenMP, CUDA обязывает знать организацию памяти. И все же, лишь от самой программы зависит сложность реализации разработки на CUDA.
Материал для разработчиков имеет отличную документацию, а также хорошие примеры реализации в коде. Программистам, которые были знакомы с технологиями MPI и OpenMP, процесс познания данной технологии будет несложным. Фундаментом для API является расширенный язык C, чтобы показывать код с языка C, комплект средств разработки CUDA содержит компилятор командной строки NVCC, который основан на компиляторе Open64.
Укажем основные свойства CUDA:
• единое аппаратное и программное решение для параллельных вычислений на графических процессорах NVIDIA;
• поддерживаемых решений начиная с мобильных заканчивая мультичипами.
• основой выбран язык С;
• хорошие стоковые библиотека численного анализа FFT и BLAS;
• оптимальный обмен данными между центральным и графическим процессорами;
• связь с OpenGL и DirectX;
• поддержка 32-разрядных и 64-разрядных операционных систем: Windows, Lynux, MacOS X;
• доступна для разработки на низком уровне.
Среда разработки CUDA:
• NVCC компилятор;
• FFT и BLAS библиотеки;
• профилировщик;
• GDB отладчик для видео процессоров;
• драйвер выполнения CUDA;
• пособие по программированию;
• комплект средств разработки разработчика CUDA.
В качестве примеров исходного кода: параллельная битовая сортировка, фильтр Собеля, шумоподавление, транспонирование матриц, свертка изображения, дискретные вейвлет-преобразования, пример взаимодействия с Direct3D и OpenGL, использование библиотек CUBLAS и CUFFT, , параллельный генератор случайных чисел Мерсенна Twister, вычисление большого массива гистограмм, снижения уровня шума, и тому подобное.
Преимущества и ограничения CUDA
Графический конвейер глазами программиста – это набор стадий обработки. Все делится на два блока: геометрии и растеризации. Первый генерирует треугольники, а второй в сою очередь генерирует пиксели, которые отображаются на мониторе. Ранняя модель GPGPU выглядит следующим образом:
Для перемещения вычислений на графический процессор в рамках такой модели, нужен специальный подход. Рассмотрим сложение векторов, для этого нужно либо отрисовывать фигуру на экране, либо в буфере. Когда растрируется фигура, для всех пикселей цвет вычисляется по пиксельному шейдеру. Программа для каждого пикселя записывает считанные с текстуры входные данные, складывает и записывает их в буфер. Весь этот трудоёмкий процесс необходим для того же, что в других языках выполняется одним оператором.
Таким образом, GPGPU являясь весьма сложным для обучения ресурсом, себя ограничивает. Даже если данного ограничения недостаточно, есть целый список. Сейчас стало ясно, что ранее созданные методы GPGPU ни что иное как «танцы с бубнами», ведь хотя есть возможность пользоваться всей мощностью GPU, тут нет никакого удобства. Алгоритмы показаны растеризацией, а данные показаны в виде текстуры. Следует отметить, очень специфическую модель памяти и реализацию.
Аппаратная архитектура и программное обеспечение, предназначенные для вычислений на графических процессорах, различна от GPGPU предшествующих моделей тем, что программы для графических процессоров Nvidia пишутся на языке С, используя стандартный синтаксис данного языка, индексы, а также, чтобы получить доступ к вычислительным возможностям видеочипов необходимо минимум расширений.
Преимущества CUDA сравнимо к GPGPU вычислениям:
• внешний вид программирования CUDA реализован на всем известном языке С, которые способствует обучению CUDA;
• обмен данными системы и видеопамяти лучше продуман;
• Нет зависимости от графического API;
• можно записывать данные по любым адресам, память представлена линейно;
• есть аппаратная реализация битовых и целочисленных операций.
Недостатки CUDA:
• отсутствует рекурсия;
• в блоке существует ограничение в 32 потока;
• CUDA принадлежит Nvidia и не является Open Source.
Главные плюсы CUDA относительно методов GPGPU возникают из-за того, что эта архитектура предназначена для качественного применения неграфических вычислений на графическом процессоре и использование языка C, без необходимости приводить алгоритмы в удобный графический вид. CUDA предлагает новый способ вычислений на графических процессорах, которая не использует графический API, предлагая оперативное запоминающее устройство (рассеивают или собираются). Эта архитектура лишена недостатков и GPGPU использует все исполнительные блоки, а также расширение возможностей в связи с целочисленной арифметикой и битовые операции сдвига.
Кроме того, CUDA открывает некоторые аппаратные функции, которые недоступны из API графики, например, совместно используемой памяти. Это память небольшого объема (16 килобайт в многопроцессорной системе), которые могут быть доступны блоки потоков. Это позволяет кэшировать часто используемые данные и может обеспечить более высокую скорость по сравнению с использованием образцов текстуры для выполнения этой задачи. Это, в свою очередь, снижает чувствительность пропускной способности параллельных алгоритмов для многих приложений. Например, это полезно для линейной алгебры, быстрого преобразования Фурье, и фильтров для обработки изображений.
Легкий в CUDA и доступа к памяти. Программный код в API данных графических выходов в виде 32 значений с плавающей точкой одинарной точности в заранее предопределенной области, а также поддерживает scatter, неограниченное количество записей по любому адресу. Эти преимущества дают возможность выполнять на GPU некоторых алгоритмов, которые не могут быть эффективно реализован с использованием методов GPGPU на основе графических API.
Кроме того, в текстурах графические API, в любом случае, сохраняют данные, этот процесс нуждается в заблаговременно загонять большие масивы в текстуры, что усложняет задачу и требует чтобы мы пользовались специальный адресацией. CUDA разрешает брать данные из любого адреса. У CUDA улучшенный обмен между процессором и графическим процессором. И программирование на ассемблере в CUDA тоже реализовано.
3.2.2.OpenCL
OpenCL (Open Computing Language – открытый язык вычислений) –Фреймворк для написания компьютерных программ, связанных с параллельными вычислениями на различных графических и центральных процессорах.
Ключевыми отличиями используемого языка от Си (стандарт ISO 1999 года) являются:
Отсутствие поддержки указателей на функции, рекурсии, битовых полей, массивов переменной длины (VLA), стандартных заголовочных файлов
Расширения языка для параллелизма: векторные типы, синхронизация, функции для Work-items/Work-Groups
Квалификаторы типов памяти: _global, _local, _constant, _private
Иной набор встроенных функций
OpenCL задумывался как технология для создания приложений, которые могли бы исполняться в гетерогенной среде. Более того, он разработан так, чтобы обеспечивать комфортную работу с такими устройствами, которые сейчас находятся только в планах и даже с теми, которые еще никто не придумал. Для координации работы всех этих устройств гетерогенной системе всегда есть одно «главное» устройство, который взаимодействует со всеми остальным посредствами OpenCL API. Такое устройство называется «хост», он определяется вне OpenCL.
OpenCL предоставляет программисту низкоуровневый API, через который он взаимодействует с ресурсами устройства. OpenCL API может напрямую поддерживаться устройством, либо работать через промежуточный API (как в случае NVidia: OpenCL работает поверх CUDA Driver API, поддерживаемый устройствами), это зависит от конкретной реализации и не описывается стандартом.
Программная модель. (Programming Model) Модель исполнения OpenCL поддерживает две программные модели: параллелизм данных (Data Parallel) и параллелизм заданий (Task Parallel), так же поддерживаются гибридные модели. Основная модель, определяющая дизайн OpenCL, – параллелизм данных.
Программная модель с параллелизмом данных. Эта модель определяет вычисления как последовательность инструкций, применяемых к множеству элементов объекта памяти. Пространство индексов, ассоциированное с моделью исполнения OpenCL, определяет Work-Item и как данные распределяются между ними. В строгой модели параллелизма данных существует строгое соответствие один к одному между Work-Item и элементом в объекте памяти, с которым kernel может работать параллельно. OpenCL реализует более мягкую модель параллелизма данных, где строгое соответствие один к одному не требуется. OpenCL предоставляет иерархическую модель параллелизма данных. Существует два способа определить иерархическое деление. В явной модели программист определяет общее число элементов, которые должны исполняться параллельно и так же каким образом эти элементы будут распределены по группам. В неявной модели программист только определяет общее число элементов, которые должны исполняться параллельно, а разделение по рабочим группам выполняется автоматически.
Программная модель с параллелизмом заданий. В этой модели каждая копия kernel исполняется независимо от какого-либо пространства индексов. Логически это эквивалентно исполнению kernel'а на вычислительном блоке (CU) с группой, состоящей из одного элемента. В такой модели пользователи выражают параллелизм следующими способами:
используют векторные типы данных, реализованные в устройстве;
устанавливают в очередь множество заданий;
устанавливают в очередь наивные kernel, использующие программную модель, ортогональную к OpenCL.
Существование двух моделей программирования – также является универсальностью. Для современных GPU и Cell хорошо подходит первая модель. Но не все алгоритмы можно эффективно реализовать в рамках такой модели, а так же есть вероятность появления устройства, архитектура которого будет неудобна для использования первой модели. В таком случае вторая модель позволяет писать специфичные для другой архитектуры приложения.
Из чего состоит платформа OpenCL. Платформа OpenCL позволяет приложениям использовать хост и одно или несколько OpenCL-устройств как одну гетерогенную параллельную компьютерную систему. Платформа состоит из следующих компонент:
OpenCL Platform Layer: позволяет хосту обнаруживать OpenCL-устройства, опрашивать их свойства и создавать контекст.
OpenCL Runtime: среда исполнения позволяет программе на хосте управлять контекстами после того как они были созданы.
Компилятор OpenCL: компилятор OpenCL создает исполняемые файлы, содержащие OpenCL–kernel. Язык программирования OpenCL-C реализуется компилятором, который поддерживает подмножество стандарта языка ISO C99 с расширениями для параллелизма.
OpenCL является универсальной, при этом она остается низкоуровневой, позволяя оптимизировать приложения под конкретную архитектуру. Так же она обеспечивает кроссплатформенность при переходе от одного типа OpenCL-устройств к другому.
