Untitled
unknown
plain_text
4 years ago
4.3 kB
8
Indexable
#include "utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <mpi.h>
#define PACKAGE_SIZE 10
#define DATA 0
#define RESULT 1
#define FINISH 2
#define MIN 0
#define MAX 1000
//#define DEBUG
int main(int argc,char **argv) {
Args ins__args;
parseArgs(&ins__args, &argc, argv);
//DANE
int sentcount=0;
int range[PACKAGE_SIZE];
int n = ins__args.arg;
int result[MAX+1] = {0};
int resulttemp[MAX+1] = {0};
MPI_Status status;
struct timeval ins__tstart, ins__tstop;
int myrank,nproc;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
MPI_Comm_size(MPI_COMM_WORLD,&nproc);
if(!myrank)
gettimeofday(&ins__tstart, NULL);
if(nproc<2){
printf("Wymagane przynajmniej dwa procesy");
MPI_Finalize();
return -1;
}
if(myrank==0){//kod mastera****************************************************************************
int* randoms = calloc(n, sizeof(int));
//wygenerowanie liczb i zapisanie ich do tablicy
for(int i=0; i<n; i++)
*(randoms+i) = (rand() % (MAX-MIN+1)) + MIN;
#ifdef DEBUG
//wysiwetla randoms
for(int i=0; i<n; i++)
printf("random %d: %d\n", i, *(randoms+i));
#endif
//z randoms wydzielam pierwsze rozdanie
for(int i=1; i<nproc; i++){
//wydziel z randoms do range 10 liczb i wyslij
for(int j=0; j<PACKAGE_SIZE; j++) {
if(sentcount<n)
range[j] = *(randoms+sentcount++);
else
range[j] = -1;
}
#ifdef DEBUG
//wyswietla pierwsze rozdania
printf("Pierwsze rozdanie do %d\n", i);
for(int j=0; j<PACKAGE_SIZE; j++)
printf("range %d: %d\n", j, range[j]);
printf("**********\n");
#endif
MPI_Send(range,PACKAGE_SIZE, MPI_INT, i, DATA, MPI_COMM_WORLD);
}
do { //wysylam dalsze zakresy jak jakis slave wroci
MPI_Recv(&resulttemp,MAX+1, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
for(int i=MIN; i<=MAX; i++)
result[i] += resulttemp[i];
#ifdef DEBUG
printf("Uzupełniłem result o dane od %d\n", status.MPI_SOURCE);
#endif
//przygotuj nową paczkę i wyślij
if(sentcount<n){
//wydziel z randoms do range 10 liczb i wyslij
for(int i=0; i<PACKAGE_SIZE; i++) {
if(sentcount<n)
range[i] = *(randoms+sentcount++);
else
range[i] = -1;
}
MPI_Send(range,PACKAGE_SIZE, MPI_INT, status.MPI_SOURCE, DATA, MPI_COMM_WORLD);
}
} while(sentcount<n);
//odebranie pozostałych pakietów
int rejProc = 1; //gdy za malo pakietow to trzeba czekac na jednego slave'a mniej???
if(n <= (nproc-1) * PACKAGE_SIZE)
rejProc = 2;
for(int i=0; i<nproc-rejProc; i++){
MPI_Recv(&resulttemp, MAX+1, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
for(int j=MIN; j<MAX+1; j++)
result[j] += resulttemp[j];
#ifdef DEBUG
printf("Odebrałem ostatnie wyliczenia od %d\n", status.MPI_SOURCE);
#endif
}
//zamkniecie slave'ow
for(int i=1; i<nproc;i++)
MPI_Send(NULL, 0, MPI_INT, i, FINISH, MPI_COMM_WORLD);
int resultCtr = 0;
for(int i=MIN; i<MAX+1; i++){
printf("%d -> %d razy\n", i, result[i]);
resultCtr += result[i];
}
printf("W sumie mamy %d liczb", resultCtr);
free(randoms);
} else {//kod slave'a *********************************************************************************
do {
MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
if(status.MPI_TAG == DATA) {
//odbierz dane i pogrupuj
MPI_Recv(range, PACKAGE_SIZE, MPI_INT, 0, DATA, MPI_COMM_WORLD, &status);
//wyzerowanie wyniku;
for(int i=MIN; i<MAX+1; i++)
resulttemp[i] = 0;
//obliczenia
for(int i=0; i<PACKAGE_SIZE; i++){
if(range[i]>-1)
resulttemp[range[i]]++;
}
#ifdef DEBUG
//wyswietlenie wynikow pracy slave'a
printf("Wykonanie slave'a nr %d\n", myrank);
for(int i=MIN; i<MAX+1; i++){
printf("ilosc %d: %d\n", i, resulttemp[i]);
}
printf("**********\n");
#endif
MPI_Send(&resulttemp, MAX+1, MPI_INT, 0, RESULT, MPI_COMM_WORLD);
}
} while(status.MPI_TAG!=FINISH);
}
if (!myrank) {
gettimeofday(&ins__tstop, NULL);
ins__printtime(&ins__tstart, &ins__tstop, ins__args.marker);
}
MPI_Finalize();
return 0;
}Editor is loading...