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

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

Этапы алгоритма моделирования, исполняемые на CPU






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

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

· Создать объект (в DirectX – объект типа Graphics­DeviceManager), реализующий доступ к графическому процессору;

Рис. 6.6. Операции, исполняемые центральным процессором

· Выделить память (т.е., описать переменные) для массивов, в которых будут храниться входные данные, – координаты частиц и параметры потенциа­лов взаимодействия, – а также выходные данные – компоненты векторов сил, действующих на ионы;

· Представить входные данные в форме, требуемой для их передачи графи­ческому процессору;

· Выделить память для хранения координат вершин квада (описание поня­тия «квад» приведено выше) и задать значения этих координат;

· Обратиться к текстовому файлу, содержащему код шейдера (программы для графического процессора). Откомпилировать этот код и записать получен­ную программу в память, доступную графическому процессору (перечисленные задачи программируются несложно, поскольку в библиотеке XNA2 для этого есть стандартные процедуры);

· Передать графическому процессору исходные данные;

· Исполнить необходимые расчёты;

· Скопировать результат из рендер-цели для дальнейшего использова­ния в программе на центральном процессоре;

Операции, которые необходимо выполнить для организации расчёта, обобщены в блок-схеме на рис. 6.6.

6.3.2. Процедуры на C#, обеспечивающие работу с графическим процессором

Ниже приведён текст программы на C#, в котором выделены и прокоммен­тированы все перечисленные этапы. В этом тексте присутствуют и все необхо­димые вспомогательные операции, также с комментариями.

private void InitGPU() /* Подготовительные операции для расчёта на графическом процессоре */

{

//Локальная переменная, представляющая графический процессор

gpu = graphics.GraphicsDevice;

 

//Создаем текстуру размером w * h, в которой будут храниться координаты и типы частиц. Количество ячеек в этой текстуре (w*h) должно совпадать с количеством частиц в кристалле, либо превышать это количество (в последнем случае «лишние» ячейки не исполь­зуют­ся). Расчёт на GPU будет наиболее быстрым, если w и h кратны 32.

in_pos = new Texture2D(gpu, w, h, 1, TextureUsage.None, SurfaceFormat.Vector4);

 

//Создаём рендер-цель – текстуру размером w * h, в которую попадет результат рас­чета сил – в её ячейках будут храниться силы, действующие на каждый из ионов.

out_force = new RenderTarget2D(gpu, w, h, 1, SurfaceFormat.Vector4, RenderTargetUsage.PreserveContents);

 

// Задаем текстуру размером 2 * 2, с параметрами парного межчастичного потенциала

in_coefs = new Texture2D(gpu, 2, 2, 1, TextureUsage.None, SurfaceFormat.Vector4);

float[] data = new float[2 * 2 * 4];

for (int u = 0; u < 2; u++)

for (int v = 0; v < 2; v++) //здесь 2 цикла могли быть заменены одним по i от 0

//до < количества пар> - 1

{

int i = (u * 2 + v) * 4;

data[i] = (float)coefs[i++];

data[i] = (float)coefs[i++];

data[i] = (float)coefs[i++];

data[i] = (float)coefs[i++];

}

in_coefs.SetData< float> (data); //in_coefs - переменная типа Texture2D

 

//Задаем квад (вершинные и текстурные координаты, соответственно).

//Y-координата текстуры инвертирована по отношению к Y-координате вершины,

//т.к. ось Y направлена снизу вверх в пространстве вершин и сверху вниз в пространстве экрана.

 

float du = 0.5f / w, dv = 0.5f / h;

// смещения для адресации текселей по центрам

//(в случае текстур с размерами не равными степени числа 2

quad = new VertexBuffer(gpu, typeof(VertexPositionTexture), 4, BufferUsage.None); //переменная типа VertexBuffer

quad.SetData< VertexPositionTexture> (new VertexPositionTexture[] {

new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0 + du, 0 + dv)),

new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1 + du, 0 + dv)),

new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0 + du, 1 + dv)),

new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1 + du, 1 + dv))

}); // кубу в пространстве сопоставлены смещенные углы плоскости

gpu.Vertices[0].SetSource(quad, 0, VertexPositionTexture.SizeInBytes); //размер квада

gpu.VertexDeclaration = new VertexDeclaration(gpu, VertexPositionTexture.VertexElements); //неясно, что

 

//Задаем шейдер и его входные параметры.

//Компиляция текстового файла с шейдером

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

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

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

//Записывает программу эффекта в память видеокарты

fx = new Effect(gpu, e.GetEffectCode(), CompilerOptions.None, null); //переменная типа Effect

//Выбирает роцедуру из кода эффекта, которую надо будет выполнять

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

//Передача на видеокарту координат частиц

fx.Parameters[" in_pos" ].SetValue(in_pos); //видимо, in_pos и in_coefs описаны в шейдере как входные текстуры

//Передача на видеокарту параметров потенциалов взаимодействия

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

}

private void ForceGPU()

{

int i, u, v;

 

//Задаем текстуру с координатами и типами частиц

float[] data = new float[w * h * 4];

 

/* Текстура представляет собой таблицу с размером w по горизонтали и h по вертикали.

* В каждой ячейке таблицы находится 4-х-вектор, хранящий координаты и тип ионов.

* Номер частицы в линейном массиве i вычисляется по формуле i = v * w + u

*/

for (v = 0; v < h; v++)

for (u = 0; u < w; u++)

{

i = v * w + u;

data[i * 4 + 0] = (float)pos[i * 3 + 0];

data[i * 4 + 1] = (float)pos[i * 3 + 1];

data[i * 4 + 2] = (float)pos[i * 3 + 2];

data[i * 4 + 3] = type[i] / 2f;

}

in_pos.SetData< float> (data); //in_pos - переменная типа Texture2D

 

//Задаем новую рендер-цель, сохраняя старую.

RenderTarget2D old_render_target = (RenderTarget2D)gpu.GetRenderTarget(0); //Зачем нужно преобразование типа?

gpu.SetRenderTarget(0, out_force); //out_force - переменная типа RenderTarget2D

gpu.Clear(new Color(0, 0, 0, 0)); //Обнуление сил в рендер-цели

 

fx.Begin(); //спросить, что делает Begin. Загружает в память?

for (i = 0; i < ions; i++)

{

//Обновляем ссылку на рендер-цель (необходимо для корректного выполнения операции += в шейдере)

gpu.SetRenderTarget(0, null); fx.Parameters[" out_force" ].SetValue(out_force.GetTexture());

gpu.SetRenderTarget(0, out_force);

//Передаем в шейдер текстурные координаты i-й частицы.

u = i % w; v = i / w; //очевидно, % - остаток от деления

fx.Parameters[" u_i" ].SetValue((u + 0.5f) / w); //передаётся центр ячейки

fx.Parameters[" v_i" ].SetValue((v + 0.5f) / h); //передаётся центр ячейки

 

//Вычисляем взаимодействие i-й частицы со всеми остальными.

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

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

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

}

fx.End(); //В цикле по всем частицам заполняется одна и та же рендер-цель

 

//Восстанавливаем старую рендер-цель.

gpu.SetRenderTarget(0, old_render_target);

 

//Получаем результат из новой рендер-цели

data = new float[w * h * 4];

for (i = 0; i < 3; i++) gpu.Textures[i] = null;

out_force.GetTexture().GetData< float> (data); //out_force - массив с рендер-целью

for (v = 0; v < h; v++)

for (u = 0; u < w; u++)

{

i = v * w + u;

force[i * 3 + 0] = data[i * 4 + 0];

force[i * 3 + 1] = data[i * 4 + 1];

force[i * 3 + 2] = data[i * 4 + 2];

}

}







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



Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

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

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

ПРОФЕССИОНАЛЬНОЕ САМОВОСПИТАНИЕ И САМООБРАЗОВАНИЕ ПЕДАГОГА Воспитывать сегодня подрастающее поколение на со­временном уровне требований общества нельзя без по­стоянного обновления и обогащения своего профессио­нального педагогического потенциала...

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

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

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

Краткая психологическая характеристика возрастных периодов.Первый критический период развития ребенка — период новорожденности Психоаналитики говорят, что это первая травма, которую переживает ребенок, и она настолько сильна, что вся последую­щая жизнь проходит под знаком этой травмы...

РЕВМАТИЧЕСКИЕ БОЛЕЗНИ Ревматические болезни(или диффузные болезни соединительно ткани(ДБСТ))— это группа заболеваний, характеризующихся первичным системным поражением соединительной ткани в связи с нарушением иммунного гомеостаза...

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