Студопедия — Пример программы
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Пример программы






Ниже мы подробно рассмотрим программу, запускающую сложение матриц на графическом процессоре. Текст программы написан на языке C#. Мы не будем исчерпывающе комментировать синтаксис этого языка, но детально прокомментируем операции, исполняемые над данными для видеокарты.

· Подключение необходимых библиотек. Используется стандартная библиотека System, а кроме того – библиотека Microsoft.Xna.Framework, упрощающая подготовку данных для графического процессора. Раздел этой библиотеки Microsoft.Xna.Framework.Graphics подключаем отдель­но, чтобы сократить в тексте программы описание доступа к ресурсам этого раздела.

using System;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Graphics;

 

public class GPGPU: Microsoft.Xna.Framework.Game

{

· Описание переменных, используемых программой

/* Задаётся размер матрицы, количество элементов в строке/столбце */

int size = 3;

/* Описываем переменную graphics класса GraphicsDeviceManager и затем инициализируем эту переменную операцией graphics = new GraphicsDeviceManager(this). Эта переменная будет обеспечивать доступ к процедурам для управления графическим процессором из библиотеки Microsoft.Xna.Framework */

GraphicsDeviceManager graphics;

· Стандартные процедуры, реализующие исполнение программы на C#

/* Ниже описаны процедуры, которые будут последовательно испол­нены сразу после запуска программы. Процедуры Main и Initialize являются стандартными для проектов на C#. Внутри процедуры Initialize находится вызов процедуры MatrixSum(), которая и осуществляет суммирование матриц на графическом процессоре. */

static void Main(string[] args) { using (GPGPU game = new GPGPU()) game.Run(); }

public GPGPU() { graphics = new GraphicsDeviceManager(this); }

protected override void Initialize()

{

base.Initialize();

MatrixSum();

Exit();

}

 

· Процедура, суммирующая матрицы с использованием GPU

private void MatrixSum()

{

/* Выше была введена переменная graphics класса GraphicsDevice­Manager. В этом классе есть нужный нам подкласс GraphicsDevice. Создаём переменную gpu этого подкласса */

GraphicsDevice gpu = graphics.GraphicsDevice;

· Выделение памяти для рендер-цели

/* Созданная в начале программы переменная size = 3 задаёт размеры матриц (3´ 3), которые мы будем складывать. Теперь создается рендер-цель – массив 3´ 3, в который будет выво­диться результат расчетов. Соответствующая переменная называется tex_target. Она является не простым массивом 3´ 3, а принадлежит к классу RenderTarget2D из библиотеки Microsoft.­Xna.­Framework. Кроме самого массива, в объектах этого класса хранятся некоторые дополнительные параметры, в частности – указатель на переменную gpu, который задаёт конкретную видеокарту, для которой создаётся рендер-цель. */

RenderTarget2D tex_target = new RenderTarget2D(gpu, size, size, 1, SurfaceFormat.Single);

· Выделение памяти для текстур с исходными данными

/* Создаются текстуры, – массивы размера size*size, - в которых будут храниться исходные матрицы. Как и рендер-цель, соответст­вующие переменные являются не простыми массивами, а принад­лежат к более сложному классу Texture2D, в объектах которого, кроме самих массивов, хранятся дополнительные параметры. Как и выше, значения этих параметров устанавливаются при создании новой переменной класса, строкой new Texture2D(gpu, size, size, 1, ResourceUsage.­Dynamic, SurfaceFormat.Single, ResourceManage­ment­Mode.Manual), значениями внутри скобок. */

Texture2D tex_matrix1 = new Texture2D(gpu, size, size, 1, ResourceUsage.Dynamic, SurfaceFormat.Single, ResourceManagement­Mode.Manual);

Texture2D tex_matrix2 = new Texture2D(gpu, size, size, 1, Resource­Usage.Dynamic, SurfaceFormat.Single, ResourceManagement­Mode.­Manual);

· Заполнение массивов исходных данных конкретными значениями

/* Теперь, задаём конкретные значения элементов исходных матриц. Сначала эти значения записываются в одномерные массивы matrix1 и matrix2 размеров size * size. Элементы a ij и b ij после преобразования матриц к одномерным массивам будут иметь номера j * size + i. Затем, мы копируем созданные массивы в текстуры класса Texture2D tex_matrix1 и tex_matrix2 операциями tex_matrix1.­SetData< float> (matrix1) и tex_matrix2.SetData< float> ­(matrix2). */

float[] matrix1 = new float[size * size], matrix2 = new float[size * size];

for (int j = 0; j < size; j++)

for (int i = 0; i < size; i++)

{

matrix1[j * size + i] = j * size + i;

matrix2[j * size + i] = i * size + j;

}

tex_matrix1.SetData< float> (matrix1);

tex_matrix2.SetData< float> (matrix2);

· Установление соответствия между целочисленными индексами элементов матриц и текстурными координатами этих элементов

/*Следующая задача – установление соответствия между целочисленными индексами элементов матриц 3´ 3 и текстурными координатами этих же элементов внутри квадрата (-1; -1)-(1; 1), или quad’а, которыми будет оперировать графический процессор, а также внутри квадрата (0; 0)-(1; 1), в который отображается массив результатов (рендер-цель). Для этого достаточно задать соответствие между индексами «крайних» элементов матриц и координатами вершин квадрата. Соответствие это показано в таблице 5.1. При необходимости рассмотрения матриц других размеров, знаменатель 6 нужно заменить на значение 2*size.

Таблица 5.1

Соответствие между координатами вершин quad’а (-1; -1)-(1; 1) и координатами элементов складываемых матриц

Вершины quad’а Координаты элементов рендер-цели
(-1; 1) (1/6; 1/6)
(-1; -1) (1/6; 1+1/6)
(1; 1) (1+1/6; 1/6)
(1; -1) (1+1/6; 1+1/6)

 

Метод определения координат элементов проиллюстрирован также на рис. 5.2. Видно, что приведённые формулы действительно обеспечивают попадание эле­ментов массива 3´ 3 в необходимые области. Учтён также тот факт, что ось Y на экране (и в рендер цели) направлена сверху вниз.

Третья пространстваенная координата во входных данных у нас не используется, поэтому в конструкторах вида Vector3(-1, 1, 0) третья координата равна нулю, тогда как первые два значения задают координаты вершин quad’а */

float dx = 0.5f / size, dy = 0.5f / size; // смещения для адресации центров текселей

VertexPositionTexture[] v = new VertexPositionTexture[] {

new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0 + dx, 0 + dy)),

new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0 + dx, 1 + dy)),

new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1 + dx, 0 + dy)),

new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1 + dx, 1 + dy))

};

/* Следующей, стандартной, строкой выделяется область памяти для хранения координат вешин quad’а. Этих вершин 4, чем и обусловлен размер 4 * VertexPositionTexture.SizeInBytes */

VertexBuffer quad = new VertexBuffer(gpu, 4 * VertexPosition­Texture.SizeInBytes, ResourceUsage.None, ResourceManagementMode.­Automatic);

quad.SetData< VertexPositionTexture> (v);

VertexDeclaration quadVertexDeclaration = new VertexDeclaration­(gpu, VertexPositionTexture.VertexElements);

· Компилирование эффектов, содержащих шейдеры

/* В библиотеку Microsoft.Xna.Framework встроен компилятор текстовых файлов, содержащих шейдеры для графического процессора, таких как sum.fx (начало примера и Приложение 1). Следующая строка компилирует файл sum.fx и запи­сывает полученную программу (в машинных кодах) в область оперативной памяти, на которую указывает переменная e типа CompiledEffect. */

CompiledEffect e = Effect.CompileEffectFromFile(" sum.fx", null, null, CompilerOptions.None, TargetPlatform.Windows);

/* Проверка успешности компиляции */

if (! e.Success) throw new Exception(e.ErrorsAndWarnings);

· Выбор шейдера, который будет исполняться

/* Создаётся новая переменная, описывающая эффект, который будет исполняться на графическом процессоре. В качестве кода эффекта выбирается откомпилированная программа, на которую указывает переменная e. */

Effect fx = new Effect(gpu, e.GetEffectCode(), CompilerOptions.None, null);

/* В качестве запускаемой на видеокарте процедуры выбирается техника sum из файла sum.fx (описана выше) */

fx.CurrentTechnique = fx.Techniques[" sum" ];

· Копирование исходных данных в видеопамять, доступную графическому процессору

/* В качестве исходных данных передаём эффекту fx текстуры с исходными данными tex_matrix1 и tex_matrix2, которые мы уже создали в начале программы: */

fx.Parameters[" tex_matrix1" ].SetValue(tex_matrix1);

fx.Parameters[" tex_matrix2" ].SetValue(tex_matrix2);

/* Задаем выходные параметры: quad и рендер-цель: */

gpu.Vertices[0].SetSource(quad, 0, VertexPositionTexture.SizeInBytes);

gpu.VertexDeclaration = quadVertexDeclaration;

gpu.SetRenderTarget(0, tex_target);

· Исполнение шейдера на графическом процессоре

fx.Begin();

fx.CurrentTechnique.Passes[" sum" ].Begin();

gpu.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);

fx.CurrentTechnique.Passes[" sum" ].End();

fx.End();

· Получение результата из рендер-цели и сохранение его в текстовом файле

/* Копирование массива результатов из видеопамяти в оперативную память, доступную центральному процессору */

gpu.ResolveRenderTarget(0);

/* Создаём текстовый файл для записи результата */

using (System.IO.StreamWriter w = new System.IO.StreamWriter­(" results.txt"))

{

/* Создаём одномерный массив, в который будут скопированы данные из рендер-цели, для дальнейшей обработки центральным процессором */

float[] matrix3 = new float[size * size];

/* Копирование данных из рендер цели в массив matrix3. Аргумент < float> означает, что данные будут скопированы в виде скалярных чисел одинарной точности */

tex_target.GetTexture().GetData< float> (matrix3);

/* Запись данных из массива matrix3 в текстовый файл */

for (int j = 0; j < size; j++)

{

for (int i = 0; i < size; i++) w.Write(" \t{0}", matrix3[j * size + i]);

w.WriteLine();

}

}}}

 







Дата добавления: 2014-12-06; просмотров: 647. Нарушение авторских прав; Мы поможем в написании вашей работы!



Шрифт зодчего Шрифт зодчего состоит из прописных (заглавных), строчных букв и цифр...

Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...

Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Деятельность сестер милосердия общин Красного Креста ярко проявилась в период Тритоны – интервалы, в которых содержится три тона. К тритонам относятся увеличенная кварта (ув.4) и уменьшенная квинта (ум.5). Их можно построить на ступенях натурального и гармонического мажора и минора.  ...

Понятие о синдроме нарушения бронхиальной проходимости и его клинические проявления Синдром нарушения бронхиальной проходимости (бронхообструктивный синдром) – это патологическое состояние...

Опухоли яичников в детском и подростковом возрасте Опухоли яичников занимают первое место в структуре опухолей половой системы у девочек и встречаются в возрасте 10 – 16 лет и в период полового созревания...

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

Вопрос 1. Коллективные средства защиты: вентиляция, освещение, защита от шума и вибрации Коллективные средства защиты: вентиляция, освещение, защита от шума и вибрации К коллективным средствам защиты относятся: вентиляция, отопление, освещение, защита от шума и вибрации...

Задержки и неисправности пистолета Макарова 1.Что может произойти при стрельбе из пистолета, если загрязнятся пазы на рамке...

Studopedia.info - Студопедия - 2014-2024 год . (0.011 сек.) русская версия | украинская версия