psychogamer Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 δε ξέρω γιατί δε μου την βγάζει την τιμή σωστά θέλω να υπολογίζει την μέση τιμή π.χ ο καθε processor να παίρνει απο κάποιους αριθμούς κ να τους προσθέτει και ύστερα να γυρνάει το αποτ στον 0 processor κ αυτός να διαιρεί με το πλήθος. Y.Γ για p processors #include <stdio.h> #include "mpi.h" main(int argc, char** argv) { int my_rank; int p,x,mesi_timi,fin_mesi_timi,num; // p einai oi processors int source,target; int tag1=50, tag2=60, tag3=70; int n; int data[100]; int data_loc[100]; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p); if (my_rank == 0) { printf("Dose plithos aritmon:\n"); scanf("%d", &n); // posous arithmous theloume gia ipologismo mesis printf("Dose tous %d arithmous pou thes:\n", n); for (x=0; x<n; x++) scanf("%d", &data[x]); // dinei tous arithmous for (target = 1; target < p; target++) MPI_Send(&n, 1, MPI_INT, target, tag1, MPI_COMM_WORLD); num = n/p; x=num; // prepei na gnwrizei to plithos i diergasia 1 for (target = 1; target < p; target++) { // stelnoume dedomena MPI_Send(&data[x], num, MPI_INT, target, tag2, MPI_COMM_WORLD); // tis dieythinseis mnimis stelnw x+=num; } //ayxanoume to x +num ayto exei na kanei k me posous processors exeis for (x=0; x<num; x++) data_loc[x]=data[x]; } else { MPI_Recv(&n, 1, MPI_INT, 0, tag1, MPI_COMM_WORLD, &status);// ayth einai i alli diergasia i 1 k dexete tis times apo ton 0 tag1 gia na steiloume tag1 gia paralabi num = n/p; // num stoixia paralamvanw MPI_Recv(&data_loc[0], num, MPI_INT, 0, tag2, MPI_COMM_WORLD, &status); // ta idia me to send ginete k kateythian sto data[] } mesi_timi = 0; // arxikopoioume mia metavliti 0 opou tha exei to apotelesma for (x=0; x<num; x++) //xekiname apo to 0 gia ti einai i proti thesi { mesi_timi = mesi_timi + data_loc[x]; mesi_timi = mesi_timi / n; } if (my_rank != 0) { MPI_Send(&mesi_timi, 1, MPI_INT, 0, tag3, MPI_COMM_WORLD); //i diergasia 0 paralamvani apo oles tis ipoloipes } else { fin_mesi_timi = mesi_timi; printf("\n Apotelesma of process %d: %d\n", my_rank, mesi_timi); // ta stelnoume sto 0 k ta result ta pigenoume sto final prosthetodas ta for (source = 1; source < p; source++) { MPI_Recv(&mesi_timi, 1, MPI_INT, source, tag3, MPI_COMM_WORLD, &status); fin_mesi_timi = mesi_timi; // to teliko result printf("\n Apotelesma of process %d: %d\n", source, mesi_timi); } printf("\n\n\n Teliko Apotelesma mesis timis: %d\n", fin_mesi_timi); } MPI_Finalize(); }
gon1332 Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 Αν και το πρόγραμμα που βλέπω είναι απλό, αυτή η στοίχιση μου προξένησε πονοκέφαλο. Αλλαξέ την ώστε να διαβάζεται. Δώσε και μία περιγραφή του τί προσπαθείς να κάνεις με αυτό. 1
psychogamer Δημοσ. 19 Νοεμβρίου 2015 Μέλος Δημοσ. 19 Νοεμβρίου 2015 οκ θέλω να υπολογίζει την μέση τιμή π.χ ο καθε processor να παίρνει απο κάποιους αριθμούς κ να τους προσθέτει και ύστερα να γυρνάει το αποτ στον 0 processor κ αυτός να διαιρεί με το πλήθος
Apoll Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 Για να καταλάβουμε, θες να βρεις το average στο array ή το median αριθμό;
psychogamer Δημοσ. 19 Νοεμβρίου 2015 Μέλος Δημοσ. 19 Νοεμβρίου 2015 το average στον συγκεκριμένο πίνακα
gon1332 Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 Το μέγεθος του input διαιρείται πάντα ακριβώς με το πλήθος των διεργασιών; Πχ εσύ δίνεις 100. Οι διεργασίες που βάζεις διαιρούν ακριβώς το 100;
Apoll Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 το average στον συγκεκριμένο πίνακα Το λάθος σου τουλάχιστον σε πρώτη ματιά, είναι στο πως υπολογίζεις αυτή. for (x=0; x<num; x++) //xekiname apo to 0 gia ti einai i proti thesi { mesi_timi = mesi_timi + data_loc[x]; mesi_timi = mesi_timi / n; } Πρώτα θα προσθέτεις ΟΛΕΣ τις τιμές και μετά θα διαιρέσεις. Απλά μαθηματικά. Και αν χρησιμοποιούσες .ΝΕΤ Framework θα το έγραφες χωρίς όλα αυτά τα for απλά to_onoma_tou_array.Average(); //Σε C#.NET to_onoma_tou_array.Average() // Σε VB.NET
psychogamer Δημοσ. 19 Νοεμβρίου 2015 Μέλος Δημοσ. 19 Νοεμβρίου 2015 ναι το διόρθωσα το συγκεκριμένο αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν
Apoll Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 ναι το διόρθωσα το συγκεκριμένο αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν Για multithreading σε αφηνώ μόνο σου στην συγκεκριμένη γλώσσα. Εγώ χρησιμοποιώ .ΝΕΤ, οπότε δεν έχω τέτοιες έννοιες. Δημιουργώ το thread ή χρησιμοποιώ στο αντικείμενο backgroundworker, κάνουν την δουλειά και καθαρίζουν πίσω τους. Αφήνωντας στο OS να κάνει την διαχείρηση των cores.
gon1332 Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 ναι το διόρθωσα το συγκεκριμένο αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν Σε ποιον αναφέρεσαι εδώ;
psychogamer Δημοσ. 19 Νοεμβρίου 2015 Μέλος Δημοσ. 19 Νοεμβρίου 2015 Σε ποιον αναφέρεσαι εδώ; σε αυτό εδώ το ποστ Το λάθος σου τουλάχιστον σε πρώτη ματιά, είναι στο πως υπολογίζεις αυτή. for (x=0; x<num; x++) //xekiname apo to 0 gia ti einai i proti thesi { mesi_timi = mesi_timi + data_loc[x]; mesi_timi = mesi_timi / n; } Πρώτα θα προσθέτεις ΟΛΕΣ τις τιμές και μετά θα διαιρέσεις. Απλά μαθηματικά. Και αν χρησιμοποιούσες .ΝΕΤ Framework θα το έγραφες χωρίς όλα αυτά τα for απλά to_onoma_tou_array.Average(); //Σε C#.NET to_onoma_tou_array.Average() // Σε VB.NET Το μέγεθος του input διαιρείται πάντα ακριβώς με το πλήθος των διεργασιών; Πχ εσύ δίνεις 100. Οι διεργασίες που βάζεις διαιρούν ακριβώς το 100; αν έχω δύο processes(επεξεργαστές) π.χ δίνω στη πρώτη 50 απο αυτούς τους αριθμούς και στη δεύτερη το ίδιο και η κάθε μια τους προσθέτει και το αποτ το γυρνάει στην αρχική την process 0 π.χ και τότε αυτή τα προσθέτει και τα διαιρεί με το πλήθος δηλαδή process 1 : 50(x1+x2+x3+x4+....x50) process 2 : 50(x1...... + x50) process 1 : προσθέτει το άθροισμα των 1 και 2 και τα διαιρεί με το n #include <stdio.h> #include "mpi.h" main(int argc, char** argv) { int my_rank; int p,x,mesi_timi,fin_mesi_timi,num; // p einai oi processors int source,target; int tag1=50, tag2=60, tag3=70; int n; int data[100]; int data_loc[100]; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p); if (my_rank == 0) { printf("Dose plithos aritmon:\n"); scanf("%d", &n); // posous arithmous theloume gia ipologismo mesis printf("Dose tous %d arithmous pou thes:\n", n); for (x=0; x<n; x++) scanf("%d", &data[x]); // dinei tous arithmous for (target = 1; target < p; target++) MPI_Send(&n, 1, MPI_INT, target, tag1, MPI_COMM_WORLD); num = n/p; x=num; // prepei na gnwrizei to plithos i diergasia 1 for (target = 1; target < p; target++) { // stelnoume dedomena MPI_Send(&data[x], num, MPI_INT, target, tag2, MPI_COMM_WORLD); // tis dieythinseis mnimis stelnw x+=num; } //ayxanoume to x +num ayto exei na kanei k me posous processors exeis for (x=0; x<num; x++) data_loc[x]=data[x]; } else { MPI_Recv(&n, 1, MPI_INT, 0, tag1, MPI_COMM_WORLD, &status);// ayth einai i alli diergasia i 1 k dexete tis times apo ton 0 tag1 gia na steiloume tag1 gia paralabi num = n/p; // num stoixia paralamvanw MPI_Recv(&data_loc[0], num, MPI_INT, 0, tag2, MPI_COMM_WORLD, &status); // ta idia me to send ginete k kateythian sto data[] } mesi_timi = 0; // arxikopoioume mia metavliti 0 opou tha exei to apotelesma for (x=0; x<num; x++) //xekiname apo to 0 gia ti einai i proti thesi { mesi_timi = mesi_timi + data_loc[x]; } if (my_rank != 0) { MPI_Send(&mesi_timi, 1, MPI_INT, 0, tag3, MPI_COMM_WORLD); //i diergasia 0 paralamvani apo oles tis ipoloipes } else { fin_mesi_timi = mesi_timi; printf("\n Apotelesma of process %d: %d\n", my_rank, mesi_timi); // ta stelnoume sto 0 k ta result ta pigenoume sto final prosthetodas ta for (source = 1; source < p; source++) { MPI_Recv(&mesi_timi, 1, MPI_INT, source, tag3, MPI_COMM_WORLD, &status); fin_mesi_timi = mesi_timi+fin_mesi_timi; // to teliko result printf("\n Apotelesma of process %d: %d\n", source, mesi_timi); } printf("\n\n\n Teliko Apotelesma mesis timis: %d\n", fin_mesi_timi/n); } MPI_Finalize(); }
gon1332 Δημοσ. 19 Νοεμβρίου 2015 Δημοσ. 19 Νοεμβρίου 2015 Αρχικά, για να σου γίνει συνήθεια θα σου πρότεινα να το δομίσεις έτσι: #include "mpi.h" #include <stdio.h> #include <stdlib.h> #define ARRAYSIZE 100 #define MASTER 0 float data[ARRAYSIZE]; int main (int argc, char *argv[]) { int numtasks, taskid, rc, dest, offset, i, j, tag1, tag2, source, chunksize; float mysum, sum; float update(int myoffset, int chunk, int myid); MPI_Status status; /***** Initializations *****/ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); if (numtasks % 2 != 0) { printf("Quitting. Number of MPI tasks must be divisible by 2.\n"); MPI_Abort(MPI_COMM_WORLD, rc); exit(0); } MPI_Comm_rank(MPI_COMM_WORLD,&taskid); printf ("MPI task %d has started...\n", taskid); chunksize = (ARRAYSIZE / numtasks); tag2 = 1; tag1 = 2; /***** Master task only ******/ if (taskid == MASTER){ /* Initialize the array */ /* Master does its part of the work */ /* Wait to receive results from each task */ /* Get final sum, compute average and print it */ } /* end of master section */ /***** Non-master tasks only *****/ if (taskid > MASTER) { /* Receive my portion of array from the master task */ /* Send my results back to the master task */ } /* end of non-master */ MPI_Finalize(); } /* end of main */ Δηλαδή, να έχεις σε ένα conditional τα του master και σε ένα άλλο όλα τα υπόλοιπα. Αυτό θα βοηθήσει στην κατανόηση του κώδικα και για πιο περίπλοκα προβλήματα. Αυτό που μένει είναι να συμπληρωθούν τα σχόλια που έβαλα (literal programming). Ξεκίνα να συμπληρώνεις το template που σου έδωσα. Επίσης, μπορείς να κρατήσεις έναν πίνακα. Δήλωσέ τον global. 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα