Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

δε ξέρω γιατί δε μου την βγάζει την τιμή σωστά

 

θέλω να υπολογίζει την μέση τιμή π.χ ο καθε  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();
}
Δημοσ.

Αν και το πρόγραμμα που βλέπω είναι απλό, αυτή η στοίχιση μου προξένησε πονοκέφαλο. Αλλαξέ την ώστε να διαβάζεται. Δώσε και μία περιγραφή του τί προσπαθείς να κάνεις με αυτό.

  • Like 1
Δημοσ.

οκ


θέλω να υπολογίζει την μέση τιμή π.χ ο καθε  processor να παίρνει απο κάποιους αριθμούς κ να τους προσθέτει και ύστερα να γυρνάει το αποτ στον 0 processor κ αυτός να διαιρεί με το πλήθος

Δημοσ.

Το μέγεθος του input διαιρείται πάντα ακριβώς με το πλήθος των διεργασιών; Πχ εσύ δίνεις 100. Οι διεργασίες που βάζεις διαιρούν ακριβώς το 100;

Δημοσ.

το 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

Δημοσ.

ναι το διόρθωσα το συγκεκριμένο


αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν

Δημοσ.

ναι το διόρθωσα το συγκεκριμένο

αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν

 

Για multithreading σε αφηνώ μόνο σου στην συγκεκριμένη γλώσσα. Εγώ χρησιμοποιώ .ΝΕΤ, οπότε δεν έχω τέτοιες έννοιες. Δημιουργώ το thread ή χρησιμοποιώ στο αντικείμενο backgroundworker, κάνουν την δουλειά και καθαρίζουν πίσω τους.

Αφήνωντας στο OS να κάνει την διαχείρηση των cores.

Δημοσ.

ναι το διόρθωσα το συγκεκριμένο

αυτο θα το βάλω στο 0 επεξεργαστή(αρχικό επεξεργαστή) που θα συγκεντρώνει τα αθροίσματα και ύστερα θα τα διαιρεί με το ν

Σε ποιον αναφέρεσαι εδώ;

Δημοσ.

Σε ποιον αναφέρεσαι εδώ;

 

σε αυτό εδώ το ποστ

 

 

Το λάθος σου τουλάχιστον σε πρώτη ματιά, είναι στο πως υπολογίζεις αυτή.

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();
}
Δημοσ.

Αρχικά, για να σου γίνει συνήθεια θα σου πρότεινα να το δομίσεις έτσι:

#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.

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...