У вас вопросы?
У нас ответы:) SamZan.net

Отчет по лабораторной работе 4 по курсу Разработка программных систем Выполнила- Митина Е

Работа добавлена на сайт samzan.net: 2015-07-10

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 4.3.2025

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

Государственное образовательное учреждение

высшего профессионального образования

“Московский государственный технический университет

имени Н.Э. Баумана”

(МГТУ им. Н.Э.Баумана)

Факультет «Робототехника и комплексная автоматизация» (РК)

Кафедра «Системы автоматизированного проектирования» (РК-6)

Отчет по лабораторной работе №4

по курсу

«Разработка программных систем»

 

Выполнила: Митина Е.В.

группа РК6-112

Проверил: Федорук В.Г.

Подпись_________________

Дата___________________

Москва 2011

Вариант №3

 Разработать средствами MPI параллельную программу решения двумерной нестационарной краевой задачи методом конечных разностей с использованием явной вычислительной схемы. Объект моделирования - прямоугольная пластина постоянной толщины. Подробности постановки подобной задачи даны ниже. Возможны граничные условия первого и второго рода в различных узлах расчетной сетки. Временной интервал моделирования и количество узлов расчетной сетки - параметры программы. Программа должна демонстрировать ускорение по сравнению с последовательным вариантом. 
Примечание. Использование неявной вычислительной схемы связано с решением системы ЛАУ на каждом временном слое. Следовательно, распараллеливание решения краевой задачи неявным методом сводится к распараллеливанию решения системы ЛАУ методом Гаусса. Распараллеливание же метода Гаусса проще всего реализуется в ситуации, когда матрица коэффициентов системы имеет блочно-диагональный с окаймлением вид. Матрица же коэффициентов автоматически получит такой вид, если нумерацию узлов расчетной сетки вести по такой простой схеме: сначала "внутренние" узлы всех фрагментов, на которые разбивается стержень, а в последнюю очередь - "соединительные" узлы. Кстати, сказанное выше справедливо и для метода прогонки (поскольку этот метод - частный случай метода Гаусса). См. также замечание. 

Текст программы

#include <iostream>

#include <unistd.h>

#include <cstdlib>

#include <cstring>

#include <sys/types.h>

#include <sys/time.h>

#include <stdio.h>

#include <fstream>

#include <errno.h>

#include <cmath>

#include <mpi.h>

//#define _REENTRANT

#define RES_STDOUT

using namespace std;

//=================================================================

FILE *f, *r;

float dx = 1.0;

float dy = 1.0;

float dt = 0.1;

float tcur = 0.0;

float tmax = 20.0;

float length = 99.0;

float height = 399.0;

float a = 1.0;

float ms = 1.0;

float Tu = 0.0;

float Tl = -50.0;

float Tr = 100.0;

float Td = 0.0;

float Tf = 0.0;

const float Zero = 0.00001;

int p=0;  

//=================================================================

unsigned GetTickCount (void) {

struct timeval tv;

gettimeofday(&tv, NULL);

return tv.tv_sec * 1000 + tv.tv_usec/1000;

}

//=================================================================

int main (int argc, char *argv[]) {

// f=fopen("rez.txt","w+");

// r=fopen("graf.txt","w+");

int total = 0;

int myrank = 0;

 

MPI_Init (&argc, &argv);

MPI_Comm_size (MPI_COMM_WORLD, &total);

MPI_Comm_rank (MPI_COMM_WORLD, &myrank);

cout << "Total=" << total << ", rank=" << myrank << endl;

 

length *= ms;

height *= ms;

 

int xsz = (int)(length / dx);

int ysz = (int)(height / dy);

int area = xsz * ysz;

 

float *tempr;

float *tempr_other;

float *along_X_buf;

float *personal_X_buf;

 

float *X_other, *Y_other;

float *final_temp;

 

int xvar;

int yvar;

float Tvar;

 

unsigned starttime;

unsigned endtime;

 

int *position;

int startline;

int startcol;

 

/**************************************************/

int linesperthread = (ysz-1)/total;

 

/**************************************************/

try {

 tempr = new float [area];

 tempr_other = new float [area];

 

 along_X_buf = new float [xsz*total*2];

 personal_X_buf =  new float [xsz*2];

 

 X_other = new float [xsz];

 Y_other = new float [ysz];

 

 position = new int [2*total];

 

 final_temp = new float [xsz * linesperthread + xsz];

}

catch(bad_alloc xa) {

 cerr << strerror(errno) << endl;

 exit(1);

}

 

/**************************************************/

 for(int i = 0; i < ysz; i++) {

  for(int j = 0; j < xsz; j++) {

   tempr[i * xsz + j] = Tf;

  }

 }

 

 for(int i = 0; i < xsz; i++) {

  tempr[i] = Tu;

 }

 for(int i = 0; i < xsz; i++) {

  tempr[(ysz-1) * xsz + i] = Td;

 }

 for(int i = 0; i < ysz; i++) {

  tempr[i * xsz] = Tl;

 }

 for(int i = 0; i < ysz; i++) {

  tempr[i * xsz + (xsz-1)] = Tr;

 }

 

 xvar = 0;

 yvar = 0;

 Tvar = -50.0;

 

 tempr[yvar*xsz + xvar] = Tvar;

 

 /**************************************************/

if (!myrank) {  

 starttime = 0;

 endtime = 0;

 starttime = GetTickCount();

 

 

 startline = 1;

 startcol = 0;

 

 for(int line = 0; line < ysz-1; line += linesperthread) {

  position[line/linesperthread * 2] = line + 1;

  position[line/linesperthread * 2 + 1] = 0;

 }

}

  

MPI_Bcast((void *)position, 2*total, MPI_INT, 0, MPI_COMM_WORLD);

   

startline = position[2*myrank];

startcol = position[2*myrank + 1];

/**************************************************/

//tcur = tmax-dt;

while(tcur < tmax) {

 

 tcur += dt;

 

 if (!myrank) {  

#ifdef RES_STDOUT

  cout << "Time step " << tcur  << "/" << tmax << endl;

#endif

#ifndef RES_STDOUT

  cout.setf(ios::showpoint);

  cout << "\rTime step " << tcur  << "/" << tmax;

  cout.unsetf(ios::showpoint);

#endif

 }

 

 if (!myrank) {

  tempr[yvar*xsz + xvar] = Tvar;

 

#ifdef RES_STDOUT

 // cout << "==========================" << endl;

  //for(int q = 0; q < ysz; q++) {

  // for(int w = 0; w < xsz; w++) {

   // printf("%#8.2f  ", tempr[q * xsz + w]);

  // fprintf(f,"%d %d %#8.2f \n",w, q, tempr[q * xsz + w]);

 //  }

 //  cout << endl;

 // }

// fprintf(f,"\n");

//  p++;

#endif

 }

  for(int i = startline; i < (linesperthread + startline); i++) {

   if(i >= ysz)

    break;

   

   for(int k = 1; k < (xsz-1); k++) {

    X_other[k] = tempr[i*xsz + (k+1)]*a*dt/(dx*dx) +

        tempr[i*xsz + (k-1)]*a*dt/(dx*dx) +

        tempr[i*xsz + k]*(1/dt - 2*a/(dx*dx))*dt;

   }

    

   X_other[0] = tempr[i*xsz];

   X_other[xsz-1] = tempr[i*xsz + (xsz-1)];

   

   for(int n = 0; n < xsz; n++) {

    tempr[i * xsz + n] = X_other[n];

   }

  }

 /*if (!myrank) {

#ifdef RES_STDOUT  

  cout << "==========================" << endl;

  for(int q = 0; q < ysz; q++) {

   for(int w = 0; w < xsz; w++) {

    printf("%#8.2f  ", tempr[q * xsz + w]);

   }

   cout << endl;

  }

#endif

   tempr[yvar*xsz + xvar] = Tvar;

 

 }*/

 

  if(!myrank) {

   

   for(int ri = 1; ri < total; ri++) {

    for(int b = 0; b < xsz; b++) {

     along_X_buf[ri * xsz * 2 + b] = tempr[position[2*ri] * xsz - xsz + b];

    }

   }

   

   for(int ri = 0; ri < total-1; ri++) {

    for(int b = 0; b < xsz; b++) {

     along_X_buf[ri * xsz * 2 + b + xsz] = tempr[position[2*(ri+1)] * xsz + b];

    }

   }

  }

  MPI_Scatter((void *)along_X_buf, 2*xsz, MPI_FLOAT, (void *)personal_X_buf, 2*xsz, MPI_FLOAT, 0, MPI_COMM_WORLD);

  

  if(myrank > 0) {

   for(int b = 0; b < xsz; b++) {

    tempr[startline * xsz + b - xsz] = personal_X_buf[b];

   }

  }

  

  if(myrank < (total - 1)) {

   for(int b = 0; b < xsz; b++) {

    tempr[(startline + linesperthread) * xsz + b] = personal_X_buf[b + xsz];

   }

  }

  

  for(int i = 1; i < (xsz-1); i++) {

  

    for(int k = startline; k < (linesperthread + startline); k++) {

     Y_other[k] = tempr[(k+1)*xsz + i]*a*dt/(dy*dy) +

         tempr[(k-1)*xsz + i]*a*dt/(dy*dy) +

         tempr[k*xsz + i]*(1/dt - 2*a/(dy*dy))*dt;

    }

    

    Y_other[0] = 0; //tempr[i];

    Y_other[ysz-1] = 0;  //2*tempr[(ysz-2)*xsz + i]*a*dt/(dy*dy) +

       //   tempr[(ysz-1)*xsz + i]*(1/dt - 2*a/(dy*dy))*dt;

   

   for(int n = 0; n < ysz; n++) {

    tempr[n * xsz + i] = Y_other[n];

   }

  }

  

  if(myrank > 0) {

   for(int b = 0; b < xsz; b++) {

    personal_X_buf[b] = tempr[startline * xsz + b];

   }

  }

  

  if(myrank < (total - 1)) {

   for(int b = 0; b < xsz; b++) {

    personal_X_buf[b + xsz] = tempr[(startline + linesperthread) * xsz - xsz + b];

   }

  }

  

  

  MPI_Gather((void *)personal_X_buf, 2*xsz, MPI_FLOAT, (void *)along_X_buf, 2*xsz, MPI_FLOAT, 0, MPI_COMM_WORLD);

  

  

  if(!myrank) {

   

   for(int ri = 1; ri < total; ri++) {

    for(int b = 0; b < xsz; b++) {

     tempr[position[2*ri] * xsz + b] = along_X_buf[ri * xsz * 2 + b];

    }

   }

   

   for(int ri = 0; ri < total-1; ri++) {

    for(int b = 0; b < xsz; b++) {

     tempr[position[2*(ri+1)] * xsz - xsz + b] = along_X_buf[ri * xsz * 2 + b + xsz];

    }

   }

  }

  

}

if(myrank != (total - 1)) {

 for(int l = startline; l < (startline + linesperthread); l++) {

  for(int i = 1; i < (xsz - 1); i++) {

   final_temp[(l-startline)*xsz + i] = tempr[l*xsz + i];

  }

 }

}

else {

 for(int l = startline; l < ysz; l++) {

  for(int i = 1; i < (xsz - 1); i++) {

   final_temp[(l-startline)*xsz + i] = tempr[l*xsz + i];

  }

 }

}

 

MPI_Gather((void *)final_temp, linesperthread*xsz, MPI_FLOAT, (void *)tempr_other,  linesperthread*xsz, MPI_FLOAT, 0, MPI_COMM_WORLD);

 

for(int l = 1; l < ysz; l++) {

 for(int i = 1; i < (xsz - 1); i++) {

  tempr[l*xsz + i] = tempr_other[(l-1)*xsz + i];

 }

}

/*

if(!myrank)

{

for(int yv =0 ; yv < ysz; yv++) {

 for(int xv = 0; xv < xsz; xv++) {

  fprintf(f,"%d %d %#8.2f \n", xv, yv, tempr[yv*ysz + xv]);

 }

}

fprintf(f,"\n");*/

// }

if (!myrank) {

#ifdef RES_STDOUT  

// f=fopen("rez.txt","w");

//       if(!f) { perror("ne otkrilsya"); exit(0);}

//   cout << "==========================" << endl;

//

  

//fclose(f);

// for (int k=1; k<p; k++)

//    {fprintf(r,"splot 'rez.txt' every :::%d::%d\npause 0.1\n", k, k);}

//fclose(r);

#endif

}

 endtime = GetTickCount();

 

cout << "Vremya ms: " << (endtime - starttime) << endl;

if (!myrank) {

 endtime = GetTickCount();

 cout << "\n-----------------------------------" << endl;

 cout << "Vremya ms: " << (endtime - starttime) << endl;

}

delete [] tempr;

 

delete [] along_X_buf;

delete [] personal_X_buf;

 

delete [] X_other;

delete [] Y_other;

 

delete [] position;

 

delete [] final_temp;

delete [] tempr_other;

 

MPI_Finalize();

exit(EXIT_SUCCESS);

}

Результат работы программы

 Корректность работы программы проверялась на прямоугольной пластинке шириной 10  и длиной 20.

Программа показала ускорение при решении задачи для 30000 узлов ( ширина 100, длина 300):

mpiexec -nolocal -perhost 1 -np 1 lab4 – 425мс

mpiexec -nolocal -perhost 1 -np 2 lab4 – 266мс

mpiexec -nolocal -perhost 1 -np 4 lab4 – 213мс

mpiexec -nolocal -perhost 1 -np 8 lab4 – 218мс




1.  Настоящая глава Правил распространяется на автоматические и телемеханические устройства электростанций
2. Лекція 1. Предмет психології її завдання і методи
3. вариант 8 полувагон модели 121302 основной габарит погрузки Пр
4. тема координат Система координат устанавливает начальные точки поверхности и линии отсчёта и единицы изм
5. Числительное ~ это часть речи объединенная прежде всего неморфологическими характеристиками а значениям
6. Тульский государственный университет Политехнический институт ТулГУ Кафедра Сварка литье и техн
7. Материнский капитал, как форма дополнительной поддержки семьи
8. Пристань дополнительные затраты не производились
9. Інноваційні технології навчання англійської мови та їх вплив на навчально-виховний процес
10. Эксплуатационные расходы на железнодорожном транспорте