Главная страница
Культура
Искусство
Языки
Языкознание
Вычислительная техника
Информатика
Финансы
Экономика
Биология
Сельское хозяйство
Психология
Ветеринария
Медицина
Юриспруденция
Право
Физика
История
Экология
Промышленность
Энергетика
Этика
Связь
Автоматика
Математика
Электротехника
Философия
Религия
Логика
Химия
Социология
Политология
Геология

курсовая. Решение на однопроцессорных компьютерах 2 Решение на многопроцессорных компьютерах Основные функции mpi. Численный эксперимент



Скачать 285.75 Kb.
Название Решение на однопроцессорных компьютерах 2 Решение на многопроцессорных компьютерах Основные функции mpi. Численный эксперимент
Анкор курсовая.docx
Дата 12.12.2017
Размер 285.75 Kb.
Формат файла docx
Имя файла курсовая.docx
Тип Решение
#12002


Параллельные алгоритмы решения систем линейных алгебраических уравнений

Содержание

Введение


  1. Обзор методов решения систем линейных алгебраических уравнений

  1. Прямые методы решения

  2. Итерационные методы

  3. Вариационные методы

  1. Метод Якоби

    1. Решение на однопроцессорных компьютерах

2.2 Решение на многопроцессорных компьютерах

  1. Основные функции MPI.

  2. Численный эксперимент

    1. Расчет на однопроцессорных компьютерах

    2. Расчет на многопроцессорных компьютерах

Литература
  1. Обзор методов решения систем линейных алгебраических уравнений

1.1 Прямые методы решения



Рассмотрим систему линейных алгебраических уравнений (СЛАУ) [1,2]

, (1)

где  матрица ,  искомый вектор,  заданный вектор. Будем предполагать, что определитель матрицы отличен от нуля, т.е. решение системы (1) существует.

Методы численного решения системы (1) делятся на две группы: прямые методы («точные») и итерационные методы.

Прямыми методами называются методы, позволяющие получить решение системы (1) за конечное число арифметических операций. К этим методам относятся метод Крамера, метод Гаусса, LU-метод и т.д.

Итерационные методы (методы последовательных приближений) состоят в том, что решение системы (1) находится как предел последовательных приближений при , где n номер итерации. При использовании методов итерации обычно задается некоторое малое число 0 и вычисления проводятся до тех пор, пока не будет выполнена оценка . К этим методам относятся метод Зейделя, Якоби, метод верхних релаксаций и т.д.

Следует заметить, что реализация прямых методов на компьютере приводит к решению с погрешностью, т.к. все арифметические операции над переменными с плавающей точкой выполняются с округлением. В зависимости от свойств матрицы исходной системы эти погрешности могут достигать значительных величин.
Метод Гаусса
Запишем систему Ax=f, в развернутом виде



Метод Гаусса состоит в последовательном исключении неизвестных из этой системы. Предположим, что . Последовательно умножая первое уравнение на и складывая с i-м уравнение, исключим из всех уравнений кроме первого. Получим систему





Аналогичным образом из полученной системы исключим . Последовательно, исключая все неизвестные, получим систему треугольного вида



Описанная процедура называется прямым ходом метода Гаусса. Заметим, что ее выполнение было возможно при условии, что все , не равны нулю.

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

Эта процедура получила название обратный ход метода Гаусса..

Метод Гаусса может быть легко реализован на компьютере. При выполнении вычислений, как правило, не интересуют промежуточные значения матрицы А. Поэтому численная реализация метода сводится к преобразованию элементов массива размерности (m×(m+1)), где m+1 столбец содержит элементы правой части системы.

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

Один из основных недостатков метода Гаусса связан с тем, что при его реализации накапливается вычислительная погрешность. В книге [ Самарский, Гулин показано, что для больших систем порядка m число действий умножений и делений близко к .

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

Существует метод Гаусса с выбором главного элемента по всей матрице. В этом случае переставляются не только строки, но и столбцы1. Использование модификаций метода Гаусса приводит к усложнению алгоритма увеличению числа операций и соответственно к росту времени счета. Поэтому целесообразность выбора того или иного метода определяется непосредственно программистом2.

Выполняемые в методе Гаусса преобразования прямого хода, приведшие матрицу А системы к треугольному виду, позволяют вычислить определитель матрицы

.

Метод Гаусса позволяет найти обратную матрицу. Для этого необходимо решить матричное уравнение

,

где Е единичная матрица. Его решение сводится к решению m систем



у вектора j –я компонента равна единице, а остальные компоненты равны нулю.
LU–метод
LU-метод основан на том, что если главные миноры матрицы А отличны от нуля, тогда матрицу А можно представить, причем единственным образом, в виде произведения

А=LU,

где L–нижняя треугольная матрица с ненулевыми диагональными элементами и U–верхняя треугольная матрица с единичной диагональю.
Рассмотрим СЛАУ Ax=f.



A=LU

где



или

,





Окончательно запишем





Полагая получим следующие рекуррентные формулы для вычисления элементов матрицы L и U



Если найдены матрицы L и U, то решение исходной системы (1)ID_1 сводится к последовательному решению двух систем уравнений с треугольными матрицами



LU – метод позволяет вычислить определитель матрицы А

.
Метод квадратного корня
Метод квадратного корня по своему идейному содержанию близок к LU-методу. Основное отличие в том, что он дает упрощение для симметричных матриц.ID_1

Этот метод основан на разложении матрицы А в произведение



где S–верхняя треугольная матрица с положительными элементами на главной





Из условия (2) получаются уравнения



Так как матрица А симметричная, не ограничивая общности, можно считать, что в системе (3) выполняется неравенство i≤j. Тогда (3) можно переписать в виде







В частности, при i=j получится



(4)

Далее, при i<j получим



По формулам (4) и (5) находятся рекуррентно все ненулевые элементы матрицы S.

Обратный ход метода квадратного корня состоит в последовательном решении двух систем уравнений с треугольными матрицами.



Решения этих систем находятся по рекуррентным формулам





Всего метод квадратного корня при факторизации A=SтS требует примерно операций умножения и деления и m операций извлечения квадратного корня.[1]
Метод вращений решения линейных систем
Как и в методе Гаусса, цель прямого хода преобразований в этом методе–приведение системы к треугольному виду последовательным обнулением поддиагональных элементов сначала первого столбца, затем второго и т.д.



Умножим первое уравнение исходной системы (1) на с1 ,второе на s1 и сложим их ; полученным уравнением заменим первое уравнение системы. Затем первое уравнение исходной системы умножаем на –s1 , второе на c1 и результатом их сложения заменим второе уравнение . Таким образом, первые два уравнения (1) заменяются уравнениями







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

В результате преобразований получим систему


где



Далее первое уравнение системы заменяется новым, полученным сложением результатов умножения первого и третьего уравнений соответственно на



а третье–уравнением, полученное при сложении результатов умножения тех же



где



Выполнив преобразование m-1 раз, придем к системе



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

Далее по этому же алгоритму преобразуется матрица



и т.д.

В результате m-1 этапов прямого хода система будет приведена к треугольному виду.



Нахождение неизвестных не отличается от обратного хода метода Гаусса.

Всего метод вращения требует примерно операций умножения и деления.

1.2 Вариационные методы



Вариационные итерационные методы
Связь между вариационной задачей и задачей решения СЛАУ.

Пусть , где Lnестьn-мерное евклидово пространство. Рассмотрим квадратичный функционал от u, называемый функционалом энергии:



где А — линейный оператор, , с — константа. Этот функционал совпадает с квадратичным функционалом где А* — сопряженный к А оператор. Действительно, по определению сопряженного оператора и (uA*u) = (A*uu) в силу коммутативности скалярного произведения. Тогда

так как

Без ограничения общности предположим, что оператор А самосопряженный, А = А*. В противном случае будем рассматривать задачу с оператором при решении вариационной задачи.

Будем также считать, что А — положительный оператор, т.е. A > 0, это означает, что для любого ненулевого вектора u выполнено (Au,u) > 0. Поставим задачу об отыскании элемента v, придающего наименьшее значение функционалу Ф(u):

.

Теорема Пусть А = А* > 0. В этом случае существует единственный элемент , придающий наименьшее значение квадратичному функционалу , являющийся решением СЛАУ Аu f.


Доказательство. СЛАУ Au = f имеет единственное решение v, поскольку А является невырожденным оператором в силу его положительной определенности. Покажем, что в этом случае при для любого вектора Δ имеет место: т.е. при достигается минимум квадратичного функционала .

Действительно,











т.е. при и любом имеет место. Докажем, что верно и обратное утверждение. Если элемент доставляет минимальное значение функционалу энергии, то он является решением системы линейных уравнений Из курса математического анализа известно, что в точке минимума должно выполняться условие A > 0. Вычисляя градиент, приходим к условию минимума функционала Таким образом установлена эквивалентность вариационной задачи (отыскание элемента, придающего минимум Ф(u)) и задачи о нахождении решения СЛАУ.

Заметим, что СЛАУ с самосопряженным и положительно определенным оператором А представляют собой важный класс задач в математической физике, в частности, они возникают при решении краевых задач для эллиптических уравнений. При необходимости можно произвести симметризацию по Гауссу исходной системы.
Методы градиентного и наискорейшего спуска
Метод градиентного спуска состоит в нахождении следующего приближения в итерационном процессе из предыдущего, путем смещения в направлении градиента функционала

(2.25)

, (2.26)

где А — положительно определенная симметричная матрица; αk — параметр, определяемый из заданных условий; например, из условия минимума величины



В этом случае итерационный метод называется методом наискорейшего спуска.

Так как то (2.26) приобретает вид

где (2.27)

что соответствует записи итерационного метода в форме (2.17). Здесь τk является итерационным параметром, который в методе наискорейшего спуска определяется из условия минимума функции по τk. Найдем условие этого минимума.





Здесь учтено соотношение: , поскольку и в силу коммутативности оператора А. Подставим в последние равенства из (2.27) получим откуда следует



, или где

Вектор rk называют вектором невязки.
Метод минимальных невязок
Этот итерационный метод определяется следующим образом. Пусть

как и ранее, Итерационный параметр τk на каждой итерации выбирается так, чтобы минимизировать, евклидову норму невязки . Заметим, что итерационный процесс может быть представлен в равносильном виде в терминах невязки . Тогда для квадрата евклидовой (третьей) нормы невязки получаем условие



Для отыскания минимума невязки на следующей итерации приравняем нулю производную последнего выражения по итерационному параметру τk. Получим равенство

.

Из последнего соотношения находим значение итерационного параметра
Метод сопряженных градиентов
Этот метод применяется для решения систем уравнений с самосопряженной положительной матрицей А= А* > 0.

Оптимизируем градиентный метод, выбирая параметры τ таким образом, чтобы на последующем шаге невязка была ортогональна всем предыдущим. На первом шаге ищем аналогично методу наискорейшего спуска. Получим невязки, образующие ортогональный базис. На последнем шаге невязка становится равна нулю, так как пространство конечномерно, и единственный элемент, ортогональный всем базисным векторам конечномерного пространства — нулевой. Получаем точное решение за конечное число шагов (прямой метод). Однако этот метод работает не всегда, так как при плохой обусловленности матрицы он становится вычислительно неустойчивым.

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

Из условия ортогональности невязок на двух первых шагах находим значение итерационного параметра

Построим такое приближение, чтобы учитывались две предыдущие — трехслойный итерационный метод. Фактически, при построении его применяется процесс ортогонализации Грамма – Шмидта.

Если , то — A-сопряженные невязки.

Имеем метод сопряженных градиентов.

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

Приведем последовательность расчетных формул одного из вариантов метода сопряженных градиентов.





(2.29)

где





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

  1. Метод Якоби



Постановка задачи
Возьмём систему линейных уравнений:

a\vec{x}=\vec{b}, где a=\left( \begin{array}{ccc} a_{11} & \ldots & a_{1n} \\ \vdots & \ddots & \vdots \\ a_{n1} & \ldots & a_{nn} \end{array} \right),\quad \vec{b}=\left( \begin{array}{c} b_1 \\ \vdots \\ b_n \end{array} \right)

Или \left\{ \begin{array}{rcl} a_{11}x_1 + \ldots + a_{1n}x_n& = & b_{1} \\ \ldots </h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2></h2> \\ a_{n1}x_1 + \ldots + a_{nn}x_n & = & b_{n} \end{array} \right.
Описание метода
Для того, чтобы построить итеративную процедуру метода Якоби, необходимо провести предварительное преобразование системы уравнений a\vec{x}=\vec{b}к итерационному виду \vec{x}=b\vec{x}+\vec{g}. Оно может быть осуществлено по одному из следующих правил:

  • b = e-d^{-1}a = d^{-1}(d - a),\quad \vec{g}=d^{-1}\vec{b};

  • b = -d^{-1}(l + u) = -d^{-1}(a - d),\quad \vec{g}=d^{-1}\vec{b}

  • d^{-1}_{ii} = 1 / d_{ii}, d_{ii} \neq 0,\, i = 1,2, ..., n\quad;

где в принятых обозначениях D означает матрицу, у которой на главной диагонали стоят соответствующие элементы матрицы A, а все остальные нули; тогда как матрицы U и L содержат верхнюю и нижнюю треугольные части A, на главной диагонали которых нули, Eединичная матрица.

Тогда процедура нахождения решения имеет вид:

 \vec{x}^{(k+1)} = b \vec{x}^{(k)}+\vec{g},

где k счётчик итерации.

В отличие от метода Гаусса-Зейделя мы не можем заменять x^{(k)}_i\,на x^{(k+1)}_iв процессе итерационной процедуры, т.к. эти значения понадобятся для остальных вычислений. Это наиболее значимое различие между методом Якоби и методом Гаусса-Зейделя решения СЛАУ. Таким образом на каждой итерации придётся хранить оба вектора приближений: старый и новый.
Условие сходимости
Приведем достаточное условие сходимости метода.

Теорема.
Пусть \| b \| < 1\!. Тогда при любом выборе начального приближения \vec{x}^{(0)}\!:

  1. метод сходится;

  2. скорость сходимости метода равна скорости сходимости геометрической прогрессии со знаменателем q= \|b\|\!;

  3. верна оценка погрешности: \|\vec{x}^{(k)}-\vec{x}\| < q^k \, \|\vec{x}^{(0)}-\vec{x}\|\!.



Условие остановки
Условие окончания итерационного процесса при достижении точности ε в упрощённой форме имеет вид:

\parallel x^{(k+1)}-x^{(k)}\parallel \le \varepsilon

(Существует более точное условие окончания итерационного процесса, которое более сложно и требует дополнительных вычислений)
Алгоритм
Ниже приведён алгоритм реализации на C++

#include

const double eps = 0.001; ///< желаемая точность

/// N - размерность матрицы; A[N][N] - матрица коэффициентов, F[N] - столбец свободных членов,

/// X[N] - начальное приближение, ответ записывается также в X[N];

void Jacobi (int N, double **A, double *F, double *X)

{

double * TempX = new double[N];

double norm; // норма, определяемая как наибольшая разность компонент столбца иксов соседних итераций.

do {

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

TempX[i] =- F[i];

for (int g = 0; g < N; g++) {

if (i != g)

TempX[i] += A[i][g] * X[g];

}

TempX[i] /= -A[i][i];

}

norm = fabs(X[0] - TempX[0]);

for (int h = 0; h < N; h++) {

if (fabs(X[h] - TempX[h]) > norm)

norm = fabs(X[h] - TempX[h]);

X[h] = TempX[h];

}

} while (norm > eps);

delete[] TempX;

}

    1. Решение на однопроцессорных компьютерах


#include

#include

#include

using namespace std;

void main()

{ double x[100], x0[100], b[100], a[100][100],

s, d, eps=1e-8, max, k;

int n, i, j ;
freopen("input.txt","r",stdin);

cin>>n;

for (i=1;i<=n;i++)

{

for (j=1;j<=n;j++) cin>>a[i][j];

cin>>b[i];

}

for (i=1;i<=n;i++)

{

for (j=1;j<=n;j++) cout<<<" ";

cout<<

}
k=0;

for (i=1;i<=n;i++) x[i]=0; // Начальное приближение

do

{ k++;

for (i=1;i<=n;i++) x0[i]=x[i];

max=0;

for (i=1;i<=n;i++)

{ s=0;

for (j=1;j<=n;j++) if (i!=j) s=s+a[i][j]*x0[j];

x[i]=(b[i]-s)/a[i][i];

d=fabs(x[i]-x0[i]); if (max

}

} while (max>eps);

for (i=1;i<=n;i++) cout<<"x"<<"="<<

cout<<"k="<

cout<<"d="<

}
???
#include

#include

#include

#include

#include

using namespace std;

void main()

{ double x[100], x0[100], b[100], a[100][100],

s, d, eps=1e-8, max, k, h, pi=3.1415926;

int n, i, j ;

// freopen("input.txt","r",stdin);

freopen("output.txt","w",stdout);

n=50;

h=1.0/n;

memset(a,0,sizeof(a));

for (i=1;i<=n-1;i++)

{

if (i>1) a[i][i-1]=1;

a[i][i]=-2;

if(i

b[i]=-4*pi*pi*h*h*sin(2*pi*i*h);

}
k=0;

for (i=1;i<=n-1;i++) x[i]=0; // Начальное приближение

do

{ k++;

for (i=1;i<=n-1;i++) x0[i]=x[i];

max=0;

for (i=1;i<=n-1;i++)

{ s=0;

for (j=1;j<=n;j++) if (i!=j) s=s+a[i][j]*x0[j];

x[i]=(b[i]-s)/a[i][i];

d=fabs(x[i]-x0[i]); if (max

}

} while (max>eps);

for (i=1;i<=n-1;i++) printf("%6.2lf",x[i]);

cout<

for (i=1;i<=n-1;i++) printf("%6.2lf",sin(2*pi*i*h));

cout<<"k="<

cout<<"d="<

}

    1. Решение на многопроцессорных компьютерах


#include

#include

#include

#include

void init(int m, double *B, double *g, double *x)

{ int i,j; double r;
for(i=0;i

{ x[i]=100.;

for(j=0;j

B[i*(m+1)]=-2;

if (i>0) B[i*(m+1)-1]=1;

if (i

g[i]=-4*pi*pi*h*h*sin(2*pi*i*h);

}

for(i=0;i

{ r=B[i*m+i];

for(j=0;j

g[i]=g[i]/r; B[i*m+i]=0;

}
}

double evalDiff(double *u,double *v, int m)

{ int i; double a=0.0;

for(i=0;i

{ double b;

b=v[i]-u[i];

a+=b*b;

}

return sqrt(a);

}

void matvec(double *B, double *g, double *xold, double *x, int k, int m)

{ int i;

for(i=0;i

{ int j; double a=0;

double *row=B+i*m;

for(j=0;j

x[i]=-a+g[i];

// printf("x%d=%.3lf\n",i,x[i]);

}

}

void print(double *x,int m)

{ int i;

for(i=0;i

}

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

{ int i, np, rk, m, chunk=1,I=0;

double *B, *Bloc, *g, *gloc, *x, *xloc, *xold, eps, diff, t;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD,&np);

MPI_Comm_rank(MPI_COMM_WORLD,&rk);

if(rk==0)

{

m=3; eps=0.0000001;

chunk=(m+1)/np;

B=(double*)malloc(m*m*sizeof(double));

}

MPI_Bcast(&m,1,MPI_INT,0,MPI_COMM_WORLD);

MPI_Bcast(&eps,1,MPI_DOUBLE,0,MPI_COMM_WORLD);

MPI_Bcast(&chunk,1,MPI_INT,0,MPI_COMM_WORLD);

g=(double*)malloc(m*sizeof(double));

xold=(double*)malloc(m*sizeof(double));

x=(double*)malloc(m*sizeof(double));

Bloc=(double*)malloc(chunk*m*sizeof(double));

gloc=(double*)malloc(chunk*sizeof(double));

xloc=(double*)malloc(chunk*sizeof(double));

if(rk==0)

{

init(m,B,g,xold); t=MPI_Wtime();

chunk=(m+1)/np;

}

MPI_Scatter(B,m*chunk,MPI_DOUBLE,Bloc,m*chunk,MPI_DOUBLE,0,MPI_COMM_WORLD);

MPI_Scatter(g,chunk, MPI_DOUBLE,gloc, chunk,MPI_DOUBLE,0,MPI_COMM_WORLD);

do

{ MPI_Bcast(xold,m,MPI_DOUBLE,0,MPI_COMM_WORLD);

matvec(Bloc,gloc,xold,xloc,chunk,m);

MPI_Gather(xloc,chunk,MPI_DOUBLE,x,chunk,MPI_DOUBLE,0,MPI_COMM_WORLD);

if(rk==0)

{

diff=evalDiff(xold,x,m);

memcpy(xold,x,m*sizeof(double));

}

MPI_Bcast(&diff,1,MPI_DOUBLE,0,MPI_COMM_WORLD);

I++;

} while ((diff>=eps)&&(I<=1000));

if(rk==0)

{

t=MPI_Wtime()-t;

printf("%d iterations consumed %lf seconds\n",I,t);

printf("np=%d m=%d chunk=%d\n",np,m,chunk);

print(x,m);

}

MPI_Finalize();

return 0;

}

  1. Основные функции MPI



Любая прикладная MPI-программа (приложение) должна начинаться с вызова функции инициализации MPI – функции MPI_Init. В результате выполнения этой функции создается группа процессов, в которую помещаются все процессы приложения, и создается область связи, описываемая предопределенным коммуникатором MPI_COMM_WORLD. Эта область связи объединяет все процессы-приложения. Процессы в группе упорядочены и пронумерованы от 0 до groupsize-1, где groupsize равно числу процессов в группе. Кроме этого создается предопределенный коммуникатор MPI_COMM_SELF, описывающий свою область связи для каждого отдельного процесса.

Синтаксис функции инициализации MPI_Init значительно отличается в языках C и FORTRAN:

C:

int MPI_Init(int *argc, char ***argv)

FORTRAN:

MPI_INIT(IERROR)

INTEGER IERROR

В программах на C каждому процессу при инициализации передаются аргументы функции main, полученные из командной строки. В программах на языке FORTRAN параметр IERROR является выходным и возвращает код ошибки.
Функция завершения MPI-программ MPI_Finalize
C:

int MPI_Finalize(void)

FORTRAN:

MPI_FINALIZE(IERROR)

INTEGER IERROR

Функция закрывает все MPI-процессы и ликвидирует все области связи.
Функция определения числа процессов в области связи MPI_Comm_size
C:

int MPI_Comm_size(MPI_Comm comm, int *size)

FORTRAN:

MPI_COMM_SIZE(COMM, SIZE, IERROR) INTEGER COMM, SIZE, IERROR

IN comm – коммуникатор;

OUT size – число процессов в области связи коммуникатора

comm.

Функция возвращает количество процессов в области связи коммуникатора comm.

До создания явным образом групп и связанных с ними коммуникаторов (глава 6) единственно возможными значениями параметра COMM являются MPI_COMM_WORLD и MPI_COMM_SELF, которые создаются автоматически при инициализации MPI. Подпрограмма является локальной.
Функция определения номера процесса MPI_Comm_rank
C:

int MPI_Comm_rank(MPI_Comm comm, int *rank)

FORTRAN:

MPI_COMM_RANK(COMM, RANK, IERROR)

INTEGER COMM, RANK, IERROR

IN comm – коммуникатор;

OUT rank – номер процесса, вызвавшего функцию.

Функция возвращает номер процесса, вызвавшего эту функцию. Номера процессов лежат в диапазоне 0..size-1 (значение size может быть определено с помощью предыдущей функции). Подпрограмма является локальной.

В минимальный набор следует включить также две функции передачи и приема сообщений.
Функция передачи сообщения MPI_Send
C: int MPI_Send(void* buf, int count, MPI_Datatype datatype,

int dest, int tag, MPI_Comm comm)

FORTRAN:

MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM,

IERROR)

BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR

IN buf – адрес начала расположения пересылаемых данных;

IN count – число пересылаемых элементов;

IN datatype – тип посылаемых элементов;

IN dest – номер процесса-получателя в группе, связанной с

коммуникатором comm;

IN tag – идентификатор сообщения (аналог типа сообщения

функций nread и nwrite PSE nCUBE2);

IN comm – коммуникатор области связи.

Функция выполняет посылку count элементов типа datatype сообщения с идентификатором tag процессу dest в области связи коммуникатора comm. Переменная buf – это, как правило, массив или скалярная переменная. В последнем случае значение count = 1.
Функция приема сообщения MPI_Recv
C:

int MPI_Recv(void* buf, int count, MPI_Datatype datatype,

int source, int tag, MPI_Comm comm, MPI_Status *status)

FORTRAN:

MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM,

STATUS, IERROR)

BUF(*) INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM,

STATUS(MPI_STATUS_SIZE), IERROR

OUT buf – адрес начала расположения принимаемого сообщения;

IN count – максимальное число принимаемых элементов;

IN datatype – тип элементов принимаемого сообщения;

IN source – номер процесса-отправителя;

IN tag – идентификатор сообщения;

IN comm – коммуникатор области связи;

OUT status – атрибуты принятого сообщения.

Функция выполняет прием count элементов типа datatype сообщения с идентификатором tag от процесса source в области связи коммуникатора comm.

Более детально об операциях обмена сообщениями мы поговорим в следующей главе, а в
заключение этой главы рассмотрим функцию, которая не входит в очерченный нами минимум, но которая важна для разработки эффективных программ. Речь идет о функции отсчета времени – таймере. С одной стороны, такие функции имеются в составе всех операционных систем, но, с другой стороны, существует полнейший произвол в их реализации. Опыт работы с различными операционными системами показывает, что при переносе приложений с одной платформы на другую первое (а иногда и единственное), что приходится переделывать – это обращения к функциям учета времени. Поэтому разработчики MPI, добиваясь полной независимости приложений от операционной среды, определили и свои функции отсчета времени.
Функция отсчета времени (таймер) MPI_Wtime
C:

double MPI_Wtime(void)

FORTRAN:

DOUBLE PRECISION MPI_WTIME()

Функция возвращает астрономическое время в секундах, прошедшее с некоторого момента в прошлом (точки отсчета). Гарантируется, что эта точка отсчета не будет изменена в течение жизни процесса. Для хронометража участка программы вызов функции делается в начале и конце участка и определяется разница между показаниями таймера.

{

double starttime, endtime;

starttime = MPI_Wtime();

… хронометрируемый участок …

endtime = MPI_Wtime();

printf("Выполнение заняло %f секунд\n",endtime-starttime);

}

Функция MPI_Wtick, имеющая точно такой же синтаксис, возвращает разрешение таймера (минимальное значение кванта времени).

  1. Численный эксперимент



    1. Расчет на однопроцессорных компьютерах


#include

#include

#include

#include

#include

#include

#include

using namespace std;

double x[100], x0[1001], b[1001], a[1001][1001], s, d, eps=1e-8, m, k, h, pi=3.1415926;

int n, i, j ;

void work(int n)

{

clock_t t0, t1;

//Засекаем время.

t0 = clock();

h=1.0/n;

memset(a,0,sizeof(a));

for (i=1;i<=n-1;i++)

{

if (i>1) a[i][i-1]=1;

a[i][i]=-2;

if(i

b[i]=-4*pi*pi*h*h*sin(2*pi*i*h);

}

k=0;

for (i=1;i<=n-1;i++) x[i]=0; // Начальное приближение

do

{ k++;

for (i=1;i<=n-1;i++) x0[i]=x[i];

m=0;

for (i=1;i<=n-1;i++)

{ s=0;

for (j=1;j<=n;j++) if (i!=j) s=s+a[i][j]*x0[j];

x[i]=(b[i]-s)/a[i][i];

d=fabs(x[i]-x0[i]); if (m

}

} while (m>eps);

for (i=1;i<=n-1;i++) printf("%6.2lf",x[i]);

cout<

for (i=1;i<=n-1;i++) printf("%6.2lf",sin(2*pi*i*h));

cout<<"k="<

cout<<"d="<

t1 = clock();

cout << "t: " <<(t1 - t0)/CLOCKS_PER_SEC << "\n";

}

void main()

{

// freopen("input.txt","r",stdin);

//freopen("output.txt","w",stdout);

work(50);

//work(100);

//work(101);

//work(1000);

getch();

}

4.2 Расчет на многопроцессорных компьютерах


Не успела.

Литература




    1. А. А. Букатов, В. Н. Дацюк, А. И. Жегуло “Программирование многопроцессорных вычислительных систем”

    2. Л. И. Турчак “Основы численных методов”

    3. А. А. Самарский “Введение в теорию разностных схем”

    4. А. А. Самарский, А. В. Гулин “Численные методы”

1


2

написать администратору сайта