- •230100 – Информатика и вычислительная техника
- •Часть 2. Алгоритмы цифровой обработки изображений 58
- •Часть 3. Методические указания для практических и лабораторных работ 109
- •Введение
- •Часть 1. Программирование графического адаптера nvidia с использованием технологии cuda
- •Краткая история развития графических адаптеров
- •Архитектура nvidia cuda
- •Архитектура gpu-приложения
- •Основные различия между cpu и cuda-устройством
- •Различие возможностей между поколениями cuda-устройств
- •Инструментарий cuda Toolkit
- •Установка
- •Проверка правильности установки
- •Компиляция примеров
- •Прикладные программные интерфейсы cuda
- •Особенности компиляции
- •Опции компилятора nvcc
- •Профайлер
- •Отладка программ в режиме эмуляции устройства
- •Среда разработки nvidia Parallel Nsight
- •Подключаемые библиотеки
- •Библиотека cublas
- •Библиотека cufft
- •Часть 2. Алгоритмы цифровой обработки изображений
- •Видоизменение гистограммы изображения
- •Основы пространственной фильтрации
- •Сглаживающие пространственные фильтры
- •Сглаживание изображений локальным усреднением
- •Сглаживание по обратному градиенту
- •Сглаживающий сигма-фильтр
- •Сглаживание по наиболее однородным областям
- •Медианный фильтр
- •Описание метода медианной фильтрации
- •Одномерный медианный фильтр
- •Зависимость качества работы медианного фильтра от размера апертуры
- •Двумерный медианный фильтр
- •Пространственные фильтры выделения границ областей
- •Линейные методы выделения границ областей. Лапласиан
- •Нелинейные методы выделения границ областей
- •Оператор Превита
- •Частотные фильтры
- •Сглаживающий частотный фильтр
- •Частотный фильтр повышения резкости
- •Гомоморфная фильтрация
- •Морфологическая фильтрация
- •Операции математической морфологии
- •Дилатация
- •Алгебраические свойства дилатации и эрозии
- •Применение морфологической дилатации
- •Применение морфологической эрозии
- •Размыкание и замыкание
- •Применение морфологических операций размыкания и замыкания
- •Основные морфологические алгоритмы
- •Выделение границ.
- •Заполнение областей.
- •Выпуклая оболочка.
- •Утончение.
- •Утолщение.
- •Построение остова.
- •Часть 3. Методические указания для практических и лабораторных работ
- •Практическая работа №1. Введение в технологию cuda
- •Цель работы
- •Порядок выполнения работы
- •Теоретическая часть
- •Архитектура графических адаптеров nvidia.
- •Архитектура чипа g80.
- •Архитектура чипа Fermi.
- •Вычислительные способности графического процессора.
- •Среда разработки cuda.
- •Язык cuda с.
- •Модель программирования cuda.
- •Теоретическая часть Модель памяти cuda
- •Особенности глобальной памяти.
- •Особенности разделяемой памяти.
- •Теоретическая часть Программный пакет «Sarcis».
- •Команды меню.
- •Панель инструментов.
- •Механизм подключения динамических библиотек.
- •Создание внешней библиотеки
- •Пример листинга программы динамической библиотеки.
- •Медианная фильтрация
- •Варианты индивидуальных заданий
- •Выбор по дискретному критерию.
- •Выбор по среднему контрасту.
- •Выбор по среднему градиенту.
- •Выбор на основе простых статистик.
- •Параметрическая аппроксимация.
- •Моментный подход.
- •Варианты индивидуальных заданий
- •Теоретическая часть
- •Инициализация устройства.
- •Выделение памяти на gpu
- •Пересылка данных между cpu и gpu.
- •Вызов функции ядра.
- •Методические рекомендации
- •Цель работы
- •Варианты индивидуальных заданий
- •Методические рекомендации
- •Защита лабораторной работы
- •Лабораторная работа № 3. Работа с разделяемой памятью в технологии cuda
- •Порядок выполнения работы
- •Методические рекомендации
- •Методические рекомендации
- •Особенности текстурной памяти.
- •Особенности линейной текстурной памяти.
- •Защита лабораторной работы
- •Правила оформления отчета
- •Оформление титульного листа
- •Библиографический список
Методические рекомендации
Объем глобальной памяти самый большой из всех типов памяти, но в то же время эта память – самая медлительная по техническим характеристикам: скорости считывания и записи.
Можно выделить два способа оптимизации в работе с глобальной памятью:
выравнивание размеров используемых типов;
использование объединенных запросов.
Поскольку обращение к глобальной памяти происходит через чтение/запись 32/64/128 битовых слов, крайне важным является то, что адрес, по которому происходит доступ, должен быть выровнен по размеру слова, т.е. кратен размеру слова в байтах.
Так, если происходит чтение 32 битого слова по адресу 0, то потребуется одно обращение к памяти. Если же чтение будет происходить с адреса 1, то потребуются два обращения к памяти, каждое из которых будет выровнено. Первое читает по адресу 0, а второе по адресу 4 (рис. 3.15).
Рис. 3.15. Пример выровненного (сверху) и невыровненного (внизу) 4 байт блока
Выравнивание производится с помощью ключевого слова __align__(размер выравнивания).
Хотя все функции, выделяющие глобальную память, выделяют ее выровненной по 256 байтам, тем не менее проблемы с выравниванием могут возникать и в этом случае. Пусть у нас есть массив из следующих структур, выделенный в глобальной памяти:
struct vec3
{
float х, у, z;
};
Даже если каждый элемент массива (длиной в 12 байт) полностью помещается в 16 байтах, и адрес первого элемента массива выровнен по 16 байтам, то адрес следующего элемента уже не будет выровнен по 16 байтам, и его чтение потребует двух обращений. Поэтому если элементы этого массива читаются нитями, то каждое второе обращение к массиву будет осуществляться в два обращения, т.е. будет заметный проигрыш в скорости.
Проще всего это исправить, обеспечить выравнивание элементов массива, которое можно достигнуть следующим способом:
struct __align__ (16) vec3
{
float х, у, z;
};
Теперь все элементы массива будут находиться на адресах, кратных 16, что обеспечит чтение одного элемента за раз. Таким образом, хотя мы и увеличили объем выделяемой и читаемой памяти, но работа с этой памятью будет происходить заметно быстрее.
Больший прирост производительности можно получить при объединении большого количества запросов в глобальную память в один. Правильное использование этой возможности позволяет получить почти 16-кратное ускорение.
Все обращения мультипроцессора к памяти происходят независимо для каждой половины варпа. Поэтому максимальное объединение – это когда все запросы одного полуварпа удается объединить в один большой запрос на чтение непрерывного блока памяти. Для этого необходимо выполнение ряда условий, которые применяются независимо к каждой половине варпа.
Для того чтобы GPU произвел объединение запросов нитей полуварпа, необходимо, чтобы были выполнены следующие условия:
все нити обращаются к 32-битовым словам, давая в результате один 64‑байтовый блок, или все нити обращаются к 64-битовым словам, давая в результате один 128‑байтовый блок;
получившийся блок выровнен по своему размеру, т.е. адрес получающегося 64-байтового блока кратен 64, а адрес получающегося 128-байтового блока кратен 128;
все 16 слов, к которым обращаются нити, лежат в пределах этого блока;
нити обращаются к словам последовательно – k-я нить должна обращаться к k-му слову (при этом допускается, что отдельные нити пропустят обращение к соответствующим словам).
Если нити полуварпа не удовлетворяют какому-либо из данных условий, то каждое обращение к памяти происходит как отдельная транзакция.
Защита лабораторной работы
Защита лабораторной работы заключается в демонстрации работающей программы и сдаче печатного отчета, содержащего все необходимые разделы согласно требованиям данного методического пособия. Студент должен владеть теоретическими знаниями, свободно комментировать все строчки кода программы и уметь формулировать выводы о проделанной работе.
Лабораторная работа № 5. Оптимизации приложений с использованием текстурной памяти
Цель работы
Целью работы является закрепление знаний о работе с моделью памяти в технологии CUDA и изучение механизма оптимизации приложений с использованием текстурной памяти.
Порядок выполнения работы
Написать программу на графическом процессоре согласно индивидуальному варианту.
Исходные данные в задаче необходимо располагать в текстуры (cudaArray текстурную память).
Сравнить время выполнения алгоритмов (через глобальную, через разделяемую и через текстурную память)
Теоретическая часть
Особенности константной памяти.
Константная память используется тогда, когда в ядро необходимо передать много различных данных, которые будут одинаково использоваться всеми потоками ядра.
Объявление глобальной переменной с именем contsData для использования в качестве константной памяти:
__constant__ float contsData [256];
Копирование данных с центрального процессора в константную память:
cudaMemcpyToSymbol (constData, hostData, sizeof (data), 0, cudaMemcpyHostToDevice);
Использование внутри ядра ничем не отличается от использования любой глобальной переменной на хосте.
