- •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
- •Цель работы
- •Порядок выполнения работы
- •Методические рекомендации
- •Методические рекомендации
- •Особенности текстурной памяти.
- •Особенности линейной текстурной памяти.
- •Защита лабораторной работы
- •Правила оформления отчета
- •Оформление титульного листа
- •Библиографический список
Теоретическая часть
Разработка приложения с использованием архитектуры CUDA ничем не отличается от создания компьютерной программы на любом языке программирования. Важно лишь разбираться в принципах организации параллельных вычислений.
Любое CUDA-приложение, должно включать следующие этапы:
Выбор и инициализацию видеокарты;
Выделение массивов данных в памяти GPU;
Загрузки данных на устройство;
Вычисление в GPU через функцию ядра;
Копирование вычисленных данных из GPU памяти в ОЗУ;
Освобождение выделенных ресурсов GPU.
Инициализация устройства.
Для управления устройствами, поддерживающими технологию CUDA, можно использовать функцию cudaGetDeviceCount, возвращающую количество устройств и функцию cudaGetDeviceProperties, описывающую свойства каждого устройства.
Функция cudaSetDevice используется для выбора устройства: cudaSetDevice(device). Устройство должно быть выбрано раньше любого вызова __global__ функции, если этого не произошло, по умолчанию ставится устройство с номером 0. Если требуется работать с несколькими устройствами, то необходимо использовать несколько потоков в программе.
Выделение памяти на gpu
Одним из способов выделения памяти в CUDA является использование функций cudaMalloc и cudaMallocPitch.
Функция cudaMalloc имеет следующий прототип:
cudaError_t cudaMalloc(void** devPtr, size_t count); где devPtr – указатель, в который записывается адрес выделенной памяти;
count – размер выделяемой памяти в байтах.
Возвращает:
cudaSuccess – при удачном выделении памяти;
cudaErrorMemoryAllocation – при ошибке выделения памяти.
Для выделения памяти под двухмерные массивы более подходящей является функция cudaMallocPitch, которая осуществляет выравнивание строк массива для более эффективного доступа к памяти. При этом в параметре pitch возвращается размер строки в байтах:
cudaError_t cudaMallocPitch (void ** devPtr, size_t * pitch,size_t width, size_t height)
Для выделения памяти на центральном процессоре помимо стандартных функций операционной системы можно воспользоваться функцией cudaMallocHost.
cudaError_t cudaMallocHost(void** hostPtr, size_t count);
Функция выделяет память на CPU в режиме блокировки от подкачки. Данный способ выделения памяти сильно ускоряет обмен данными с GPU. Однако частое использование данной функции может привести к падению производительности центрального процессора.
Пересылка данных между cpu и gpu.
Для взаимодействия CPU и GPU используется глобальная память, размеры которой могут варьироваться от нескольких сотен мегабайт до нескольких гигабайт. Скорость передачи данных с хоста на устройство ограничивается пропускной способностью шины PCI Express.
Рассмотренные выше функции управляют выделением памяти на GPU, к которой центральный процессор не имеет непосредственного доступа. Поэтому CUDA API предоставляет специальные функции, которые позволяют копировать память как между CPU и GPU, так и в пределах GPU.
Для копирования данных между хостом и устройством используются функции cudaMemcpy и cudaMemcpyAsync, которые имеют следующий прототип:
cudaError_t cudaMemcpy( void * dst, const void * src, size_t count, enum cudaMemcpyKind kind );
cudaError_t cudaMemcpyAsync ( void * dst, const void * src, size_t count, enum cudaMemcpyKind kind, cudaStream_t stream );
где dst – указатель, содержащий адрес места назначения копирования;
src – указатель, содержащий адрес источника копирования;
count – размер копируемого ресурса в байтах;
kind – направление копирования может принимать значения:
cudaMemcpyHostToDevice – c хоста на устройство,
cudaMemcpyDeviceToHost – с устройства на хост,
cudaMemcpyDeviceToDevice – с устройства на устройство,
cudaMemcpyHostToHost – с хоста на хост.
stream – описение потока, в котором запускается функция.
Возвращает:
cudaSuccess – при удачном копировании,
cudaErrorInvalidValue – неверный указатель памяти в видеокарте,
cudaErrorInvalidMemcpyDirection – неверное направление.
Функция cudaMemcpyAsync ассинхронная, т.е. управление в основную программу хоста возвратится до реального ее выполнения. Для завершения работы функции необходимо использовать средства синхронизации, например функцию cudaThreadSynchronize().
Функция cudaMemcpyAsync работает только с памятью выделенной с помощью функции cudaMallocHost.
Для очистки выделенных ресурсов служат следующие функции:
cudaFreeHost (void * ptr) – очищает память с адреса, на который указывает ptr.
cudaFree (void *devPtr) – очищает память с адреса, указанного в devPtr.
