Курсовая работа (т): Изучение возможностей массивно-параллельных вычислений в применении к задачам математической физики

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам


Поставим задачу не только вычислить веса и узлы, но и проверить их на каком-нибудь простом интеграле. В качестве подынтегральной функции выберем косинус:


Интегрирование будем осуществлять на отрезке , количество узлов положим равным ста. Также отдельно зададим границы интервала , чуть позже это будет полезным:


Получим узлы, находя корни полинома Лежандра  сотой степени:


Посчитаем веса:

Найдем значение интеграла с помощью квадратурной формулы Гаусса, учитывая, что интервал интегрирования не совпадает с интервалом для этой формулы, а значит необходимо перераспределить узлы на новом отрезке, масштабируя расстояния между ними:


Теперь вычислим интеграл стандартными средствами Maple и сравним результаты:


Последнее действие даёт единицу, что означает адекватность узлов и весов.

5.3 Реализация на C++

Сейчас нужно экспортировать полученные результаты в программу на С++. Для этого просто сохраним данные в двух текстовых файлах -  и  и будем подгружать содержимое этих файлов в самом начале работы программы с помощью функций:


Для того чтобы вычислить коэффициенты , которые с учётом соображений, изложенных в пунктах и , определяются формулой:


также удобно воспользоваться распараллеливанием. Как и в предыдущей главе, зададим функцию  в виде , длину струны положим равной единице, а количество коэффициентов  оставим равным двумстам пятидесяти шести:


Расчёт будем осуществлять при помощи CUDA. Создаём вспомогательную функцию, которая будет выполняться процессором и отвечать за перенос данных из памяти CPU в память GPU и обратно, а также за вызов функции-ядра:


В качестве аргументов будем передавать указатели на массивы, содержащие веса и узлы квадратурной формулы, а также указатель на массив, в который будем сохранять получившиеся коэффициенты. Внутри функции  прежде всего произведем копирование данных из памяти процессора в память видеокарты:


а также выделим в памяти GPU место под массив коэффициентов:


Необходимо посчитать всего двести пятьдесят шесть коэффициентов, для чего будем использовать соответствующее число нитей. Сгруппируем все эти нити в одномерные блоки по сто двадцать восемь нитей в каждом и сформируем сетку из блоков:


Вызовем функцию-ядро, которая будет называться :


и после того, как она отработала, скопируем результаты обратно в память процессора и освободим память видеокарты:


Функция  будет выполняться видеопроцессором и осуществлять одни и те же действия для множества нитей. Вот её листинг:


Коэффициенты двумерного случая будем представлять, как и в главе , в виде произведения коэффициентов каждого измерения. Удобно в такой ситуации сохранять получаемые результаты в массиве типа , где -компонента будет содержать коэффициенты, насчитанные для -измерения, а -компонента - для  Текст исполняющих функций при этом меняется мало: массив объявляется как -массив, и это необходимо учитывать каждый раз, когда осуществляется выделение места под коэффициенты, перенос данных в память видеокарты или обратно. Листинг функции :


В этом случае процесс вычисления коэффициентов распараллеливается на двести пятьдесят шесть нитей, каждая из которых выполняет расчёт одного - и одного -коэффициента. Можно поступить и по-другому: не меняя типа массива , сделать двумерной сетку и двумерными же блоки нитей:


тогда процесс распараллеливается на  нитей, и каждая нить рассчитывает только один коэффициент. Функция  будет выглядеть так:


В случае, если функция начального состояния мембраны по какой-то причине не представима в виде произведения двух независимых функций по двум измерениям, последний способ особенно удобен.

Итак, в этой главе был предложен метод получения входящих в решение коэффициентов с помощью квадратурной формулы Лежандра-Гаусса. В следующей главе рассмотрим оставшиеся до получения решения шаги.

6. ПАРАЛЛЕЛЬНЫЙ РАСЧЕТ АМПЛИТУД

6.1 Массивно-параллельный расчет амплитуд

Вернемся к решению задачи о колебаниях:


для которого уже найдены . Так как бесконечное суммирование осуществить программно, вообще говоря, невозможно, оборвем ряд на некотором :


В четвертой и пятой главах при расчёте коэффициентов  было задано равным двумстам пятидесяти шести; при желании несложно сделать это число значительно больше, но мы остановимся на этом значении.

Далее предлагается описывать положение струны  точками и рассчитывать их отклонения от положения равновесия в каждый момент времени, делая это с помощью массивно-параллельных вычислений. Итак, разобьем всю длину струны  точками, тогда, если известен номер  точки, то её координату можно выразить как  Создадим процедуру, которая подготавливает запуск функции-ядра и осуществляет его:


В качестве аргументов она будет принимать указатель на массив, куда будут записываться рассчитанные амплитуды, указатель на массив коэффициентов, число коэффициентов, число точек  и время, для которого необходимо выполнить расчёт. Листинг функции:

Источник: https://www.bibliofond.ru/detail.aspx?id=882805