Untitled
unknown
plain_text
3 years ago
4.3 kB
3
Indexable
Never
#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; }