Разработка и исследование распределенного клиент-серверного приложения для задач управления
на примере метода среднезначной интерполяции Лагранжа
Цель …
План
…
Реализация, испытания, анализ
Рассмотрим пример реализации метода среднезначной интерполяции Лагранжа, он достаточно просто реализуем и создаёт большую вычислительную нагрузку, что требуется для анализа производительности серверного приложения.
Программная реализация алгоритма поточечной интерполяции по методу Лагранжа
// функция интерполяции (файл int_server.cpp)
void interpolate
(
int p_numb, // Количество исходных точек
int i_numb, // Требуемое количество точек после интерполяции
float* data, // Буфер исходных данных
float* result // Буфер результата
)
{
float time[50]; // Абсциссы исходных точек
float value[50]; // Ординаты исходных точек
float coeffs[50]; // Коэффициенты
float buf,maxt,mint,step; // Промежуточные переменные
int i,j,k; // Счётчики
// Получение временных границ
maxt=data[0];
mint=data[0];
// Выделение данных
for (i=0; i<p_numb; i++)
{
time[i]=data[2*i];
value[i]=data[2*i+1];
if (time[i]>maxt) maxt=time[i];
if (time[i]<mint) mint=time[i];
}
// Расчёт коэффициента домножения для каждого из полиномов
for (i=0; i<p_numb; i++)
{
coeffs[i]=1;
for (j=0; j<p_numb; j++)
{
// Задаём множители так, чтобы в остальных
// точках значение полинома было равно нулю
if (i!=j) coeffs[i]=coeffs[i]*(time[i]-time[j]);
}
// Расчёт функции в исходной точке и получение
// коэффициента домножения
coeffs[i]=value[i]/coeffs[i];
}
// Получение шага интерполяции
step=(maxt-mint)/(i_numb-1);
// Расчёт значений интерполянта в искомых точках
for (k=0; k<i_numb; k++)
{
// Расчёт абсциссы точки
result[2*k]=mint+step*k;
result[2*k+1]=0;
// Последовательное сложение значений полиномов в точке
for (i=0; i<p_numb; i++)
{
buf=coeffs[i];
for (j=0; j<p_numb; j++)
{
if(i!=j)buf=buf*(result[2*k]-time[j]);
}
// Сохранение результата в буфер
result[2*k+1]+=buf;
}
}
return;
}
Реализация серверного приложения, решающего задачу интерполяции
#include <stdio.h>
#include <errno.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <unistd.h>
// Прототип функции интерполяции
void interpolate(int p_numb, int i_numb, float* data, float* result);
// Основная функция проекта
int main(void)
{
int rcvid; // VID клиента
float msg_buf[1002]; // Буфер приёма и передачи
name_attach_t *res; // Информация о клиенте
int p_numb; // Количество исходных точек
// Создание именованного канала
res = name_attach(NULL, "int_server", 0 );
if (res==NULL)
{
printf("Error #%d: Cant't create channel\n", errno);
return 1;
}
else printf ("Server's channel created\n");
// Цикл обработки сообщений от клиента
while(1)
{
// приём сообщения в буфер msg_buf
rcvid = MsgReceive(res->chid, &msg_buf[0], 102*sizeof(float), NULL);
if (rcvid!=0)
{
p_numb= msg_buf[1];
// Интерполяция
interpolate (msg_buf[0], msg_buf[1], &msg_buf[2], msg_buf);
// Отправка результата клиенту MsgReply(rcvid,p_numb*sizeof(float),msg_buf,p_numb*2*sizeof(floa
}
}
return 0;
}
Разработка консольного клиентского приложения, использующего сервер для выполнения интерполяции
#include <stdio.h>
#include <errno.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <unistd.h>
// Основная функция программы
int main( int argc, char **argv)
{
int p_numb, i_numb; // Количества исходных и требуемых точек
int res, i; // промежуточные переменные
int coid; // Идентификатор канала сервера
float smsg [102]; // Буфер отправляемого сообщения
float rmsg [1000]; // Буфер принимаемого сообщения
FILE* finp; // Указатель на файл исходных данных
FILE* foutp; // Указатель на файл результатов
// Если не указаны имена файлов ввода и вывода, то выход
if (argc !=3)
{
printf ("Error #1: Input and output files haven't specified.");
return 1;
}
// Открытие файла ввода
finp=fopen(argv[1],"r");
if (finp==NULL)
{
printf ("Error #6: Can't open file %s.", argv [1]);
return 6;
}
// Считывание данных из файла ввода
res=fscanf(finp," %d %d",&p_numb, &i_numb);
if (res!=2)
{
printf("Error #3: Can't get point numbers.");
return 3;
}
// Проверка допустимости значения количества исходных точек
if ((p_numb<2)||(p_numb>50))
{
printf("Error #4: Data points number must be numeric in [2..50].");
return 4;
}
// Проверка допустимости количества требуемых точек
if ((i_numb<2)||(i_numb>500))
{
printf("Error #5: Data points number must be numeric in [2..500].");
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.