Смекни!
smekni.com

«Оптимизация кластерной системы на базе pvm компьютерной лаборатории физического факультета» (стр. 8 из 9)

Динамика среднего астрономического времени работы главной задачи (рис.6).

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

Заключение.

В ходе работы были изучены основные принципы построения распределенных вычислительных систем (HPC), оптимизирована работа параллельной виртуальной машины PVM на базе компьютеризированной лаборатории физического факультета: установлено новое программное обеспечение, изучен интерфейс и принципы работы графической консоли XPVM, дана оценка сферы ее применимости, оптимизирован алгоритм тестовых программ, повышены показатели производительности кластерной системы. Поставленные цели и задачи курсовой работы достигнуты.

Список литературы.

1. PVM User’s Guide: http://www.netlib.org

2. Онлайн энциклопедия: http://ru.wikipedia.org/

3. Linux кластер – практическое руководство: http://cluster.linux-ekb.info/

4. Илья Евсеев - Использование PVM. Введение в программирование: http://www.cluster.bsu.by

5. Программа СКИФ союзного государства. PVM - параллельная виртуальная машина: http://www.skif.bas-net.by

6. Балуев А.Н. Перевод документации по PVM (мат-мех факультет СПбГУ): http://www.math.spbu.ru

7. Message Passing Toolkit: PVM Programmer's Manual: http://techpubs.sgi.com

8. Шпаковский Г.И., Серикова Н.В. Пособие по программированию матричных задач в MPI. - Минск: БГУ, - 2002. – 44 с.

Приложение.

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

//программа для нагрузочного тестирования запускается из консоли (кол-во посылок, решения)

#include <stdio.h>

#include <stdlib.h>

#include "pvm3.h"

#include "math.h"

#include <time.h>

//идентификаторы

#define msgtype_argv 0

#define msgtype_master_data 1

#define msgtype_slave_data 2

#define msgtype_slave_time 3

double x[2]; //массив для хранения решений кв.ур-ия

double timespecDiff(struct timespec *timeA_p, struct timespec *timeB_p)

{

return ((double)(timeA_p->tv_sec) + ((double)(timeA_p->tv_nsec))/1000000000)-((double)(timeB_p->tv_sec) + ((double)(timeB_p->tv_nsec))/1000000000);

}

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

{

int mytid; //переменная для иденификации основного процесс

int tids[100]; //массив значений tids для запущенных задач

long int N/*кол-во повторов решения на узле*/, i, j, k, np/*кол-во посылок по сети*/;

int nslaves/*число запущенныйх задач*/, nhosts/*количество хостов*/, narch/*количество различных форматов данных*/, master;

void raschet(double a, double b, double c); //к решению квадратного ураванения(коэффициенты a,b,c)))

double total_time_cpu_c=0; //общее время процессора

double time_cpu_master_c=0; //общее время работы процессора на локальных узлах

double time_global_master_l=0; //число тактов процессора на решение задачи

double time_slave_ci=0; //время работы процессора на локальном узле

struct pvmhostinfo *hostp; //При возврате, каждая структура pvmhostinfo содержит TID pvmd, имя хоста, имя архитектуры и относительную характеристику скорости процессора для определенного хоста в конфигурации

struct timespec start_c, start_l, end_l, end_c, start_ci, end_ci;

clock_gettime(CLOCK_MONOTONIC, &start_l); //старт точного измерения тактов процессора

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_c); //старт счета процессорного времени на решение задачи

mytid = pvm_mytid(); //регистрирует процесс в PVM, возвращает TID текущего процесса

pvm_setopt(PvmRoute, PvmRouteDirect); //``включение'' прямолинейной маршрутизации между задачами PVM

pvm_setopt(PvmFragSize,16384); //установить размер буфера передачи для сообщения

//pvm_setopt(PvmFragSize,65536); // субъективный параметр на скорость передачи не влияет

//pvm_setopt(PvmFragSize,114688); //хуже

//pvm_setopt(PvmFragSize,163840); //

//pvm_catchout(stdout); // для вывода на экран информации от подзадач

//pvm_setopt(PvmOutputTid,0);

//инициализация генератора псевдослучайных чисел

srand((unsigned)time(NULL)); //time() возвращает текущее время в сек

long double a, b, c; //переменные под коэффициенты кв.ур-ия

//определение местоположения для выполнения соответствующей части задачи.

//pvm_parent() - вернет TID задачи, которая породила задачу, сделавшую вызов

if(pvm_parent() == PvmNoParent) //если выполница, то это задача - главная порождающая остальные

{

//1 часть программы для главного узла

pvm_config( &nhosts, &narch, &hostp ); //возвращает информацию о виртуальной машине, включая количество хостов - nhost - и количество различных форматов данных - narch

//printf("%s &bsol;n",argv[0]);

/*&hostp - это указатель на декларированный пользователем массив из структур pvmhostinfo.

Размер массива должен быть длиной, по крайней мере, соответствующей nhosts.*/

//считывает число посылок по сети

sscanf(argv[1],"%lu",&np); //читает данные из argv[1], преобразовывая символы к значениям указателей на long unsigned int, в переменную np

//считывает число решений на одном узле

sscanf(argv[2],"%lu",&N); //

nslaves = 2*nhosts -1; //число запусков задач(2*число хостов-1)

printf("%d &bsol;t", nslaves+1); //печатаеть в stdout целочисленные десятичные наборы сиволы через таб длинной nslaves+1

printf("%lu&bsol;t%lu&bsol;t",np,N); //печатаеть в stdout long unsigned int наборы сиволы через tab и tab из преременных np и N

nslaves=pvm_spawn(&argv[0][0], (char**)0, 0, "", nslaves, tids); //ф-ция,которая запускает в PVM nslaves копий исполняемого файла с именем "argv[0][29]" с одинаковыми аргументами командной строки (char**)0 , на компьютере который выберет сама.

//отсылка

pvm_initsend(PvmDataInPlace); //инициализация буфера для отправки сообщения

pvm_pklong(&N, 1, 1); //упаковка в передающий буфер данных массива N длинной 1 с числом элементов 1 в одном эл-те массива

pvm_pklong(&np, 1, 1);

pvm_mcast(tids, nslaves, msgtype_argv); //присваевает сообщению идентификатор msgtype_argv и широковещательно посылает его задачам, идентификаторы которых перечислены в nslaves элементах массива tids

//цыклы для посылки по рассылки

for(j = 0; j < np; j++)

{

//задаем коэффициенты через rand

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

{

a = ((long double) rand() /((long double)RAND_MAX+1.0));

b = ((long double) rand() /((long double)RAND_MAX+1.0));

c = ((long double) rand() /((long double)RAND_MAX+1.0));

pvm_initsend(PvmDataInPlace); //инициализация буфера пересылки

pvm_pklong((long int *)(&a), 2, 1); //упаковка созданного коэф-та а

pvm_pklong((long int *)(&b), 2, 1); //упаковка созданного коэф-та b

pvm_pklong((long int *)(&c), 2, 1); //упаковка созданного коэф-та c

//отсылка коэф-тов на другие узлы для решения кв. ур-ия

pvm_send(tids[i], msgtype_master_data); //присваивает сообщению идентификатор msgtype_master_data и посылает сообщение задаче с идентификатором tids[i], т.е. всем что есть в массиве

}

//создание коэф-тов для решения ур-ия на этом узле

a = ((long double) rand() /((long double)RAND_MAX+1.0));

b = ((long double) rand() /((long double)RAND_MAX+1.0));

c = ((long double) rand() /((long double)RAND_MAX+1.0));

//решает кв.ур-ие с одними и теми же а,b,c на главном узле

for(k = 0; k < N; k++)

{

raschet(a, b, c); //посылает к решению кв.ур-ия

}

//получение решений с локальных узлов

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

{

pvm_recv(-1, msgtype_slave_data); //получение решения с друго узла

pvm_upkdouble(x , 2, 1 ); //распаковка полученного решения

}

}

//сумматор времени процессора, затр. на решение зад. на кластере

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

{

pvm_recv( -1, msgtype_slave_time); //ожидает сообщения с иденификатором msgtype_slave_time от задачи с идентификатором -1

pvm_upkdouble(&time_slave_ci, 1, 1); //распакует принятые данные из массива с указателем &time_slave_ci длинной 1 с 1 элементом указанного типа в одном элементе массива

//общее время решения ур-ия на всех локальных узлах кластера

time_cpu_master_c += time_slave_ci; //суммирует время решения задачи на других машинах

}

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_c); //окончание счета процессорного времени на решение задачи

clock_gettime(CLOCK_MONOTONIC, &end_l); //конец точного измерения тактов процессора

//общее процессорное время решения задачи на кластере

total_time_cpu_c = timespecDiff(&end_c, &start_c) + time_cpu_master_c; //сумма времен затраченных на решение задачи на кластере

time_global_master_l = timespecDiff(&end_l, &start_l); //сумма тактов процессора на решение задачи на главной машине

//печать в stdout общего процессорного времени решения задачи на всем кластере и тактов процессора на главной машине.

printf("%20.9f&bsol;t%20.9f&bsol;n", time_global_master_l, total_time_cpu_c);

}

//2 часть программы для локального узла

else

{

mytid = pvm_mytid(); //регистрирует процесс в PVM, возвращает TID текущего процесса

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ci); //начало отсчета времени работы процессора

master = pvm_parent(); //узнает идентификатор родительской задачи

pvm_recv(master, msgtype_argv); //ожидает поступления сообщения с идентификатором msgtype_argv от задачи с идентификатором master

pvm_upklong(&N, 1, 1); //распаковка N

pvm_upklong(&np, 1, 1); //распаковка np

for(j = 0; j < np; j++)

{

pvm_recv(master, msgtype_master_data); //ожидает поступления сообщения с идентификатором msgtype_master_data от задачи с идентификатором master

pvm_upklong((long int *)(&a), 2, 1); //распаковка

pvm_upklong((long int *)(&b), 2, 1); //распаковка

pvm_upklong((long int *)(&c), 2, 1); //распаковка

for(k = 0; k < N; k++)

{

raschet(a, b, c); //посылает к решению кв.ур-ия

}

pvm_initsend(PvmDataInPlace); //инициализация буфера пересылки без кодировки для отправки решения

pvm_pkdouble(x, 2, 1); //упаковка решения кв.ур-ия

//отсылка решений на главный узел

pvm_send(master, msgtype_slave_data); //присваивает сообщению идентификатор msgtype_slave_data и посылает сообщение задаче с идентификатором master

}

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ci); //конец отсчета времени работы процессора