Лабораторная работа №1. Работа с глобальной памятью" по дисциплине "Программирование графических процессоров". Вариант общий
Состав работы
|
|
|
|
Работа представляет собой rar архив с файлами (распаковать онлайн), которые открываются в программах:
- Adobe Acrobat Reader
Описание
Выполнение лабораторной работы поможет получить навыки, требующиеся для выполнения первого и третьего заданий контрольной работы.
Задание
1. Прочитайте главы теоретического материала под названиями "Отличия GPU от CPU", "Первая программа на CUDA C", "Алгоритм сложения двух векторов на GPU", "События, обработка ошибок и получение информации об устройстве", "Глобальная, локальная и константная память". Ответьте на контрольные вопросы и выполните контрольные задания, предложенные в конце этих глав (ответы на контрольные вопросы не нужно включать в отчёт по лабораторной работе).
2. Реализуйте параллельный алгоритм умножения AxV, где A – матрица, V – вектор.
3. Реализуйте параллельный алгоритм умножения VxA, где A – матрица, V – вектор.
4. Постройте графики зависимости времени выполнения алгоритма от размера матрицы и вектора (Размеры матрицы 1000x500, 1000x1000, 1500x1000, 2000x1000, 2000x1500, 2500x1500, 2500x2000).
5. Прочитайте главу "Профилирование программ", ответьте на контрольные вопросы в конце главы (ответы на контрольные вопросы не нужно включать в отчёт по лабораторной работе).
6. Проанализируйте, реализованные алгоритмы при помощи утилиты nvprof на эффективность доступа к глобальной памяти.
Методические указания по выполнению лабораторной работы
Для того чтобы распараллелить алгоритм AxV взглянем на код последовательного алгоритма. Пусть есть матрица A размером [NxM], где N – количество строк, M – количество столбцов. И вектор V размером M (для умножения нужно чтобы размер вектора совпадал с количеством столбцов в матрице). Результатом такого умножения будет вектор C размера N. Ниже представлен код алгоритма:
for(int i = 0; i < N; ++i) {
for(int j = 0; j < M) {
C[i] += A[i][j] * V[j];
}
}
Для того чтобы получить i-ый элемент результирующего вектора нужно взять i-ую строку матрицы A, все её элементы попарно умножить на элементы вектора и результат умножений сложить.
Теперь нужно выделить части не зависящие друг от друга. Если проанализировать работу алгоритма, то можно увидеть, что вычисление C[i] не зависит от вычислений, проводимых для расчёта других элементов результирующего вектора C. Тогда можно запустить код
for(int j = 0; j < M) {
C[i] += A[i][j] * V[j];
}
на разных вычислителях, а за индекс i взять порядковый номер вычислителя. На GPU таким вычислителем будет нить, а код нужно оформить в функцию-ядро. Важно помнить, что нити не существуют сами по себе, они группируются в блоки, а блоки вмещают не более 1024 нити. Но блоков можно запустить очень большое количество, поэтому будем считать, что их количество не ограничено и их нужно запустить достаточно, чтобы у каждой строки матрицы была своя нить. Количество блоков, которое понадобится можно вычислить по формуле N/THREAD_PER_BLOCK + 1, где N размер данных (в нашем случае это количество строк в матрице), а THREADS_PER_BLOCK – размер блока (если не знаете какой размер выбрать, возьмите 128. Важно чтобы размер был кратен 32). Единица прибавляется в конце т.к. если N не кратно размеру блока, то количество блоков будет на 1 меньше чем нужно, потому что при использовании целочисленного деления результат округлится до ближайшего меньшего целого значения. Из-за этого останется "хвост", который не распределён по нитям, но нам точно известно, что он меньше размера блока, поэтому добавляем ещё один блок для вычислений над этими данными. На рисунке 1 изображена схема распределения вычислений по нитям и блокам.
Рис. 1 – умножение матрицы на вектор
На рисунке видно, что каждая нить работает только с одной строкой и вектором, а результатом её работы является один элемент. После того как все нити отработают результирующий вектор будет полностью вычислен.
Ещё одна проблема – нити имеют свой номер только внутри блока. Чтобы вычислить глобальный номер нити, который будет браться вместо индекса i нужно размер блока умножить на номер блока и прибавить к нему номер нити в блоке (если забыли, где хранятся все эти величины просмотрите ещё раз теоретический материал).
Теперь опишите функцию-ядро – функцию которая будет исполняться каждой нитью GPU. Она должна принимать на вход адрес матрицы A, адрес вектора V, адрес результирующего вектора C, вычислять глобальный номер нити и в цикле вычислять элемент результирующего вектора по алгоритму, описанному выше, номер которого соответствует глобальному номеру нити.
В функции main выделите на хосте память под матрицу, вектор V и результирующий вектор и проинициализируйте их целыми числами (результирующий проинициализируйте нулями). Затем выделите память под матрицу, вектор и результирующий вектор на устройстве. Матрицу на GPU расположите в линейной памяти и используйте для её выделения функцию cudaMallocPitch. В выделенную на устройстве память скопируйте данные с хоста при помощи функции cudaMemcpy2D. Для выделения памяти на устройстве под векторы и копирования данных на устройство используйте cudaMalloc и cudaMemcpy соответственно.
После этого запустите функцию-ядро для вычислений и передайте в качестве параметра запуска размер блока и количество блоков, а в качестве параметров функции передайте адреса выделенной памяти на устройстве. После этого на хосте вызовите функцию cudaDeviceSynchronize, которая будет ожидать завершения работы всех исполняющихся нитей. Затем скопируйте при помощи функции cudaMemcpy результирующий вектор из памяти устройства в память хоста. Проверьте правильно ли сделаны расчёты.
Добавьте к коду программы замеры времени по аналогии из главы "События, обработка ошибок и получение информации об устройстве" и проведите эксперименты с указанными в задании размерами матрицы и вектора.
Главный показатель эффективности доступа к памяти – высокая пропускная способность и высокий процент попаданий в кэш (если используется кэширующий доступ к памяти). Чтобы проанализировать программу на эффективность обращения к глобальной памяти воспользуйтесь консольной утилитой nvprof и следующими метриками:
dram_utilization – уровень пропускной способности dram относительно пиковой пропускной способности (от 0 до 10).
dram_read_throughput – пропускная способность считывания из dram.
dram_write_throughput – пропускная способность записи в dram.
global_hit_rate – процент попаданий в L1/texture кэш.
gld_throughput – пропускная способность считывания из глобальной памяти
gld_reqested_throughput – эффективная пропускная способность считываний из глобальной памяти.
gld_efficiency – эффективность считываний из глобальной памяти – отношение эффективной пропускной способности считываний из глобальной памяти к общей пропускной способности считываний из глобальной памяти.
gst_throughput – пропускная способность записи в глобальную память.
gst_requested_throughput – эффективная пропускная способность записи в глобальную память.
gst_efficiency – эффективность записи в глобальную – отношение gst_requested_throughput к gst_throughput.
Проанализируйте и объясните полученные результаты.
По аналогии с реализацией параллельного алгоритма умножения матрицы на вектор реализуйте параллельный алгоритм умножения вектора на матрицу. Схема доступа нитей и блоков к данным показана на рисунке 2.
Рис. 2 – умножение вектора на матрицу
Теперь каждая нить обращается к столбцу матрицы, а не к строке.
Задание
1. Прочитайте главы теоретического материала под названиями "Отличия GPU от CPU", "Первая программа на CUDA C", "Алгоритм сложения двух векторов на GPU", "События, обработка ошибок и получение информации об устройстве", "Глобальная, локальная и константная память". Ответьте на контрольные вопросы и выполните контрольные задания, предложенные в конце этих глав (ответы на контрольные вопросы не нужно включать в отчёт по лабораторной работе).
2. Реализуйте параллельный алгоритм умножения AxV, где A – матрица, V – вектор.
3. Реализуйте параллельный алгоритм умножения VxA, где A – матрица, V – вектор.
4. Постройте графики зависимости времени выполнения алгоритма от размера матрицы и вектора (Размеры матрицы 1000x500, 1000x1000, 1500x1000, 2000x1000, 2000x1500, 2500x1500, 2500x2000).
5. Прочитайте главу "Профилирование программ", ответьте на контрольные вопросы в конце главы (ответы на контрольные вопросы не нужно включать в отчёт по лабораторной работе).
6. Проанализируйте, реализованные алгоритмы при помощи утилиты nvprof на эффективность доступа к глобальной памяти.
Методические указания по выполнению лабораторной работы
Для того чтобы распараллелить алгоритм AxV взглянем на код последовательного алгоритма. Пусть есть матрица A размером [NxM], где N – количество строк, M – количество столбцов. И вектор V размером M (для умножения нужно чтобы размер вектора совпадал с количеством столбцов в матрице). Результатом такого умножения будет вектор C размера N. Ниже представлен код алгоритма:
for(int i = 0; i < N; ++i) {
for(int j = 0; j < M) {
C[i] += A[i][j] * V[j];
}
}
Для того чтобы получить i-ый элемент результирующего вектора нужно взять i-ую строку матрицы A, все её элементы попарно умножить на элементы вектора и результат умножений сложить.
Теперь нужно выделить части не зависящие друг от друга. Если проанализировать работу алгоритма, то можно увидеть, что вычисление C[i] не зависит от вычислений, проводимых для расчёта других элементов результирующего вектора C. Тогда можно запустить код
for(int j = 0; j < M) {
C[i] += A[i][j] * V[j];
}
на разных вычислителях, а за индекс i взять порядковый номер вычислителя. На GPU таким вычислителем будет нить, а код нужно оформить в функцию-ядро. Важно помнить, что нити не существуют сами по себе, они группируются в блоки, а блоки вмещают не более 1024 нити. Но блоков можно запустить очень большое количество, поэтому будем считать, что их количество не ограничено и их нужно запустить достаточно, чтобы у каждой строки матрицы была своя нить. Количество блоков, которое понадобится можно вычислить по формуле N/THREAD_PER_BLOCK + 1, где N размер данных (в нашем случае это количество строк в матрице), а THREADS_PER_BLOCK – размер блока (если не знаете какой размер выбрать, возьмите 128. Важно чтобы размер был кратен 32). Единица прибавляется в конце т.к. если N не кратно размеру блока, то количество блоков будет на 1 меньше чем нужно, потому что при использовании целочисленного деления результат округлится до ближайшего меньшего целого значения. Из-за этого останется "хвост", который не распределён по нитям, но нам точно известно, что он меньше размера блока, поэтому добавляем ещё один блок для вычислений над этими данными. На рисунке 1 изображена схема распределения вычислений по нитям и блокам.
Рис. 1 – умножение матрицы на вектор
На рисунке видно, что каждая нить работает только с одной строкой и вектором, а результатом её работы является один элемент. После того как все нити отработают результирующий вектор будет полностью вычислен.
Ещё одна проблема – нити имеют свой номер только внутри блока. Чтобы вычислить глобальный номер нити, который будет браться вместо индекса i нужно размер блока умножить на номер блока и прибавить к нему номер нити в блоке (если забыли, где хранятся все эти величины просмотрите ещё раз теоретический материал).
Теперь опишите функцию-ядро – функцию которая будет исполняться каждой нитью GPU. Она должна принимать на вход адрес матрицы A, адрес вектора V, адрес результирующего вектора C, вычислять глобальный номер нити и в цикле вычислять элемент результирующего вектора по алгоритму, описанному выше, номер которого соответствует глобальному номеру нити.
В функции main выделите на хосте память под матрицу, вектор V и результирующий вектор и проинициализируйте их целыми числами (результирующий проинициализируйте нулями). Затем выделите память под матрицу, вектор и результирующий вектор на устройстве. Матрицу на GPU расположите в линейной памяти и используйте для её выделения функцию cudaMallocPitch. В выделенную на устройстве память скопируйте данные с хоста при помощи функции cudaMemcpy2D. Для выделения памяти на устройстве под векторы и копирования данных на устройство используйте cudaMalloc и cudaMemcpy соответственно.
После этого запустите функцию-ядро для вычислений и передайте в качестве параметра запуска размер блока и количество блоков, а в качестве параметров функции передайте адреса выделенной памяти на устройстве. После этого на хосте вызовите функцию cudaDeviceSynchronize, которая будет ожидать завершения работы всех исполняющихся нитей. Затем скопируйте при помощи функции cudaMemcpy результирующий вектор из памяти устройства в память хоста. Проверьте правильно ли сделаны расчёты.
Добавьте к коду программы замеры времени по аналогии из главы "События, обработка ошибок и получение информации об устройстве" и проведите эксперименты с указанными в задании размерами матрицы и вектора.
Главный показатель эффективности доступа к памяти – высокая пропускная способность и высокий процент попаданий в кэш (если используется кэширующий доступ к памяти). Чтобы проанализировать программу на эффективность обращения к глобальной памяти воспользуйтесь консольной утилитой nvprof и следующими метриками:
dram_utilization – уровень пропускной способности dram относительно пиковой пропускной способности (от 0 до 10).
dram_read_throughput – пропускная способность считывания из dram.
dram_write_throughput – пропускная способность записи в dram.
global_hit_rate – процент попаданий в L1/texture кэш.
gld_throughput – пропускная способность считывания из глобальной памяти
gld_reqested_throughput – эффективная пропускная способность считываний из глобальной памяти.
gld_efficiency – эффективность считываний из глобальной памяти – отношение эффективной пропускной способности считываний из глобальной памяти к общей пропускной способности считываний из глобальной памяти.
gst_throughput – пропускная способность записи в глобальную память.
gst_requested_throughput – эффективная пропускная способность записи в глобальную память.
gst_efficiency – эффективность записи в глобальную – отношение gst_requested_throughput к gst_throughput.
Проанализируйте и объясните полученные результаты.
По аналогии с реализацией параллельного алгоритма умножения матрицы на вектор реализуйте параллельный алгоритм умножения вектора на матрицу. Схема доступа нитей и блоков к данным показана на рисунке 2.
Рис. 2 – умножение вектора на матрицу
Теперь каждая нить обращается к столбцу матрицы, а не к строке.
Дополнительная информация
Уважаемый студент дистанционного обучения,
Оценена Ваша работа по предмету: Программирование графических процессоров
Вид работы: Лабораторная работа 1
Оценка:Зачет
Дата оценки: 27.02.2021
Рецензия:Уважаемый
Ваша работа зачтена.
Милешко Антон Владимирович
Оценена Ваша работа по предмету: Программирование графических процессоров
Вид работы: Лабораторная работа 1
Оценка:Зачет
Дата оценки: 27.02.2021
Рецензия:Уважаемый
Ваша работа зачтена.
Милешко Антон Владимирович
Похожие материалы
Телевидение. Лабораторная работа №1. Вариант общий
Damovoy
: 4 февраля 2021
«Сигналы простых изображений»
Цель работы
Целью работы является изучение формы и состава различных видеосигналов, измерение их временных параметров.
Задание на лабораторную работу
1. Исследовать форму и измерить временные параметры импульсов, участ-вующих в формировании ПТС, для чего соблюдая временные и амплитудные соотношения, зарисовать форму и измерить период следования и длительность ССИ, КСИ, СГИ, КГИ. Для каждого вида импульсов рассчитать скважность и частоту повторения.
2. Получить на
300 руб.
Лабораторная работа №1 по дисциплине: Информатика. Вариант общий
Roma967
: 21 ноября 2023
Лабораторная работа №1
«Технология работы с формулами на примере подсчета количества разных оценок в группе в экзаменационной ведомости»
Этап 1.
Сформируйте структуру таблицы (рис. 1) и заполните ее постоянными значениями (подпись экзаменатора ставить не надо).
В созданной рабочей книге с экзаменационной ведомостью рассчитайте:
- количество оценок (отлично, хорошо, удовлетворительно, неудовлетворительно, неявок), полученных в данной группе;
- общее количество полученных оценок.
Этап 2.
Под
350 руб.
Теория связи. Лабораторная работа №1. Вариант общий
Damovoy
: 4 февраля 2021
Тема: ИССЛЕДОВАНИЕ СПЕКТРОВ СИГНАЛОВ
Лабораторное задание
1. Изучить связь между формой видеосигнала и его спектром.
2. Изучить форму ДАМ сигнала и его спектр.
3. Изучить форму ДФМ сигнала и его спектр.
4. Объяснить различия в спектре ДАМ, ДФМ и видеосигнала.
3. Порядок выполнения работы
1. Выбрать режим видеосигнала. Изучить влияние значений уровня сигнала А1 и А0 на спектр сигнала в комплексной и вещественной форме. А1, А0 – (0 – 2.0)В.
2. Изучить влияние Т и τ на спектр сигнала в комплексно
290 руб.
Лабораторная работа №1.Линейная антенная решетка. Вариант общий.
dolgotanya
: 15 января 2025
Цель работы: исследование электрических характеристик антенной решетки.
Основные теоретические сведения. Как известно, одиночный симметричный вибратор обладает слабо выраженными направленными свойствами. Поэтому для формирования узких диаграмм направленности из одиночных вибраторов формируют системы, называемые антенными решетками. Линейной решеткой называют систему излучателей, расположенных в линию (или ряд).
110 руб.
Лабораторная работа №1 по дисциплине: Теория связи. Вариант общий
xtrail
: 25 июля 2024
Лабораторная работа №1
«Исследование спектров сигналов»
1. Цель работы
Исследование связи между временными и частотными характеристиками сигналов.
2. Описание лабораторной установки
3. Лабораторное задание
1) Изучить связь между формой видеосигнала и его спектром.
2) Изучить форму ДАМ сигнала и его спектр.
3) Изучить форму ДФМ сигнала и его спектр.
4) Объяснить различия в спектре ДАМ, ДФМ и видеосигнала.
4. Выполнение работы
4.1 Изучение связи между формой видеосигнала и его спектром
4.1.1 И
300 руб.
Лабораторная работа №1 по дисциплине: Теория информации. Вариант общий
Roma967
: 26 марта 2023
Формулировка задания
Цель работы: Экспериментальное изучение свойств энтропии Шеннона.
Среда программирования: любая с С-подобным языком программирования.
Результат: программа, тестовые примеры, отчет.
Задание:
1. Для выполнения этой практической работы необходимо иметь три файла. Объем каждого файла больше 10 Кб, формат txt.
В первом файле должна содержаться последовательность символов (количество различных символов больше 3) с равномерным распределением, т.е. символы в файле встречают
300 руб.
Лабораторная работа 1 по дисциплине: Операционные системы. Вариант общий
Roma967
: 4 января 2023
Лабораторная работа №1
«Работа с файловой системой LINUX»
Цель работы:
Изучить команды управления каталогами и файлами.
Порядок выполнения работы
1. Если вы еще не установили операционную систему LINUX, установите.
2. Включить компьютер и войти в систему LINUX , если система требует пройдите процедуру идентификации.
3. Ознакомиться с информацией, появившейся на экране монитора.
4. Выбрать на панели монитора режим «терминал».
Учимся создавать новый каталог
5. Убедитесь, что Вы находитесь в
500 руб.
Лабораторная работа №1 по дисциплине: Электротехника и электроника. Вариант общий
Учеба "Под ключ"
: 2 декабря 2022
Лабораторная работа №1
«Исследование статических характеристик полупроводниковых диодов»
1 . Цель работы
Изучить устройство полупроводникового диода, физические процессы, происходящие в нем, характеристики, параметры, а также типы и применение полупроводниковых диодов.
2. Подготовка к работе
2.1 Изучить следующие вопросы курса:
2.1.1 Электрические свойства полупроводников. Собственные и примесные полупроводники.
2.1.2 Электронно-дырочный переход, его характеристики и параметры. Прямое и обрат
400 руб.
Другие работы
ММА/ИДО Иностранный язык в профессиональной сфере (ЛТМ) Тест 20 из 20 баллов 2024 год
mosintacd
: 28 июня 2024
ММА/ИДО Иностранный язык в профессиональной сфере (ЛТМ) Тест 20 из 20 баллов 2024 год
Московская международная академия Институт дистанционного образования Тест оценка ОТЛИЧНО
2024 год
Ответы на 20 вопросов
Результат – 100 баллов
С вопросами вы можете ознакомиться до покупки
ВОПРОСЫ:
1. We have … to an agreement
2. Our senses are … a great role in non-verbal communication
3. Saving time at business communication leads to … results in work
4. Conducting negotiations with foreigners we shoul
150 руб.
Задание №2. Методы управления образовательными учреждениями
studypro
: 13 октября 2016
Практическое задание 2
Задание 1. Опишите по одному примеру использования каждого из методов управления в Вашей профессиональной деятельности.
Задание 2. Приняв на работу нового сотрудника, Вы надеялись на более эффективную работу, но в результате разочарованы, так как он не соответствует одному из важнейших качеств менеджера - самодисциплине. Он не обязателен, не собран, не умеет отказывать и т.д.. Но, тем не менее, он отличный профессионал в своей деятельности. Какими методами управления Вы во
200 руб.
Особенности бюджетного финансирования
Aronitue9
: 24 августа 2012
Содержание:
Введение
Теоретические основы бюджетного финансирования
Понятие и сущность бюджетного финансирования
Характеристика основных форм бюджетного финансирования
Анализ бюджетного финансирования образования
Понятие и источники бюджетного финансирования образования
Проблемы бюджетного финансирования образования
Основные направления совершенствования бюджетного финансирования образования
Заключение
Список использованный литературы
Цель курсовой работы – исследовать особенности бюджетного фин
20 руб.
Программирование (часть 1-я). Зачёт. Билет №2
sibsutisru
: 3 сентября 2021
ЗАЧЕТ по дисциплине “Программирование (часть 1)”
Билет 2
Определить значение переменной y после работы следующего фрагмента программы:
a = 3; b = 2 * a – 10; x = 0; y = 2 * b + a;
if ( b > y ) or ( 2 * b < y + a ) ) then begin x = b – y; y = x + 4 end;
if ( a + b < 0 ) and ( y + x > 2 ) ) then begin x = x + y; y = x – 2 end;
200 руб.