time_slave_ci = timespecDiff(&end_ci, &start_ci); //время работы процессора на локальном узле
pvm_initsend(PvmDataInPlace); //инициализация буфера пересылки без кодировки
pvm_pkdouble(&time_slave_ci, 1, 1); //упаковка
//отсылка времени работы процессора на решение ур-ия на локальном узле
pvm_send(master, msgtype_slave_time); //присваивает сообщению идентификатор msgtype_slave_time и посылает сообщение задаче с идентификатором master
}
pvm_exit(); //завершение пользование услугами PVM
return 0;
}
//алгоритм решения квадратного уравнения, коэффициентами которого являются случайные вещественные числа
void raschet(double a, double b, double c)
{
double D;
D = b*b - 4*a*c;
if(D == 0)
{
x[0] = x[1] = -b/(a);
}
if(D < 0.)
{
double t = 1/(2.*a);
x[0] = -b*t; x[1] = sqrt(-1*D)*t;
}
if(D > 0.)
{
x[0] = (-b + sqrt(D))/(a*2.); x[1] = (-b - sqrt(D))/(a*2.);
}
}
Текст программы, для имитационной модели метода Монте-Карло:
//вывод число хостов, число задач запущенных, второй аргумент, первый аргумент,
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pvm3.h>
#include <math.h>
#include <time.h>
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; /* my task id */
int tids[100]; /* slave task ids */
int nslaves, i, msgtype, nhosts, narch, master;
/*unsigned*/ long int N, S, Si, nN, nH, np;
long double Pi;
long double PiTrue = 4.0 * ((long double)atan(1.0));
long int mk(unsigned long int);
double hostcputime, /*hostlocaltime,*/ timeElapsed_ci, /*timeElapsed_li,*/ timeElapsed_c, timeElapsed_l;
struct pvmhostinfo *hostp;
struct timespec start_c, start_l, end_l, end_c, start_ci,/* start_li, end_li,*/ end_ci;
clock_gettime(CLOCK_MONOTONIC, &start_l);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_c);
mytid = pvm_mytid();/*tid master*/
pvm_setopt(PvmRoute, PvmRouteDirect);//``включение'' прямолинейной маршрутизации между задачами PVM
srand((unsigned)time(NULL));
if(pvm_parent() == PvmNoParent)
{
pvm_config( &nhosts, &narch, &hostp );
sscanf(argv[2],"%lu",&np);
sscanf(argv[1],"%lu",&N);
nslaves = np * nhosts - 1;
//число хостов, число задач запущенных на хосте, второй аргумент, первый аргумент
printf("%d\t%d\t%lu\t%lu\t", nhosts, (nslaves+1), np, N);
nslaves=pvm_spawn(&argv[0][0], (char**)0, 0, "", nslaves, tids);
nN = N / (nslaves + 1);
nH = N - nslaves * nN;
//nH, nN,
printf("%ld\t%ld\t", nH, nN);
pvm_initsend(PvmDataInPlace);
pvm_pklong(&nN, 1, 1);
pvm_mcast(tids, nslaves, 0);
S = mk(nH);
msgtype = 1;
for( i=0 ; i<nslaves ; i++ )
{
pvm_recv( -1, msgtype );
pvm_upklong( &Si, 1, 1 );
pvm_upkdouble(&timeElapsed_ci, 1, 1);
//pvm_upkdouble(&timeElapsed_li, 1, 1);
S += Si;
hostcputime += timeElapsed_ci;
//hostlocaltime += timeElapsed_li;
}
Pi = 4.0 * ((long double)S) / ((long double)N);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_c);
clock_gettime(CLOCK_MONOTONIC, &end_l);
timeElapsed_c = timespecDiff(&end_c, &start_c);
timeElapsed_l = timespecDiff(&end_l, &start_l);
//расчетное значение ПИ, погрешность вычисления
printf("%20.18Lf\t%7.1Le\t",Pi,((long double)fabs(Pi-PiTrue)));
//время астронамическое, время процессорное
printf("%20.9f\t%20.9f\n", timeElapsed_l, (timeElapsed_c + hostcputime));
}
else
{
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ci);
msgtype = 0;
pvm_recv( -1, msgtype );
pvm_upklong(&nN, 1, 1);
Si = mk(nN);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ci);
timeElapsed_ci = timespecDiff(&end_ci, &start_ci);
pvm_initsend(PvmDataInPlace);
pvm_pklong(&Si, 1, 1);
pvm_pkdouble(&timeElapsed_ci, 1, 1);
//pvm_pkdouble(&timeElapsed_li, 1, 1);
msgtype = 1;
master = pvm_parent();
pvm_send( master, msgtype );
}
pvm_exit();
}
long int mk(unsigned long int n)
{
unsigned long int i;
long int Sum;
long double x, y;
for(i = 0, Sum = 0; i < n; i++)
{
x = ((long double) rand() /((long double)RAND_MAX+1.0));
y = ((long double) rand() /((long double)RAND_MAX+1.0));
if( (x*x + y*y) <= 1.0) Sum++;
}
return Sum;}