σενάριο:
Φανταστείτε ότι εκτελούμε παράλληλη προσομοίωση (π.χ., μοντελοποίηση της πληθυσμιακής ανάπτυξης). Έχουμε μια παγκόσμια παράμετρο `αρχική_Population` που πρέπει να είναι γνωστή από * κάθε * διαδικασία στο MPI Communicator. Μόνο η διαδικασία ρίζας (διαδικασία με την κατάταξη 0) αρχικά γνωρίζει αυτήν την τιμή. Θα χρησιμοποιήσουμε το `mpi_bcast` για να διανείμει` αρχική_Population 'σε όλες τις διαδικασίες.
Παράδειγμα κώδικα (C ++)
`` c ++
#include
#include
int main (int argc, char ** argv) {
int κατάταξη, μέγεθος?
διπλό αρχικό_Population; // Παγκόσμια παράμετρο
Mpi_init (&argc, &argv);
MPI_COMM_RANK (MPI_COMM_WORLD, &RANK);
Mpi_comm_size (mpi_comm_world, &μέγεθος);
// initialize initial_population μόνο στη ριζική διαδικασία
αν (κατάταξη ==0) {
αρχική_Population =1000.0; // Παράδειγμα αρχική τιμή
std ::cout <<"Διαδικασία 0:αρχικός πληθυσμός =" <<αρχική_Population <
αρχική_Population =0.0; // Άλλες διαδικασίες αρχικοποιούνται σε μια προεπιλεγμένη τιμή (δεν έχει σημασία)
}
// μεταδίδει τον αρχικό πληθυσμό από τη διαδικασία 0 σε όλες τις διαδικασίες.
MPI_BCAST (&αρχική_Population, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// Τώρα, όλες οι διαδικασίες έχουν τη σωστή τιμή της αρχικής_πλείας.
// Εκτελέστε υπολογισμούς προσομοίωσης χρησιμοποιώντας τα κατανεμημένα δεδομένα
// Παράδειγμα:
Double Growth_Rate =0,05; // 5% ρυθμός ανάπτυξης
Double Final_Population =αρχική_Population * (1.0 + ανάπτυξη_Rate);
std ::cout <<"process" <
Mpi_Finalize ();
επιστροφή 0;
}
`` `
Επεξήγηση:
1. Αρχικοποίηση:
- `mpi_init (&argc, &argv)`:αρχικοποιεί το περιβάλλον MPI.
- `MPI_COMM_RANK (MPI_COMM_WORLD, &RANK)`:παίρνει την τάξη (ID) της τρέχουσας διαδικασίας.
- `mpi_comm_size (mpi_comm_world, &size)`:παίρνει τον συνολικό αριθμό διαδικασιών στο Communicator.
2. Αρχικοποίηση διαδικασίας ρίζας:
- `if (rank ==0)`:Ο κώδικας μέσα σε αυτό το block `if` εκτελείται μόνο στη διαδικασία 0 (η διαδικασία ρίζας).
- `αρχική_Population =1000.0 ·:Η διαδικασία ρίζας θέτει την αρχική τιμή του πληθυσμού.
3. Broadcasting με `mpi_bcast`:
- `mpi_bcast (&initial_population, 1, mpi_double, 0, mpi_comm_world);`
- `&initial_population`:Ένας δείκτης στα δεδομένα που πρόκειται να μεταδοθούν (η θέση μνήμης όπου αποθηκεύεται η` αρχική_Population`).
- `1`:ο αριθμός των στοιχείων για εκπομπή (σε αυτή την περίπτωση, ένα μόνο διπλό).
- `mpi_double`:Ο τύπος MPI των δεδομένων που μεταδίδονται.
- `0`:Η τάξη της διαδικασίας ρίζας (η διαδικασία που έχει την αρχική τιμή και την στέλνει).
- `MPI_COMM_WORLD`:Ο επικοινωνιακός (στην περίπτωση αυτή, ο προεπιλεγμένος επικοινωνίας που περιλαμβάνει όλες τις διαδικασίες).
4. Υπολογισμός προσομοίωσης:
- Μετά τις διαδικασίες `mpi_bcast`, * όλες * έχουν τη σωστή τιμή του` initial_population`.
- Ο κωδικός παραδείγματος εκτελεί έπειτα έναν απλό υπολογισμό προσομοίωσης (πολλαπλασιάζοντας με ρυθμό ανάπτυξης) και εκτυπώνει τα αποτελέσματα. Σε μια πραγματική εφαρμογή, αυτό θα ήταν όπου συμβαίνει ο παράλληλος υπολογισμός χρησιμοποιώντας τα κατανεμημένα δεδομένα.
5. Τελειοποίηση:
- `mpi_finalize ()`:Τερματίζει το περιβάλλον MPI.
Πώς λειτουργεί (κάτω από την κουκούλα):
Η λειτουργία "MPI_BCAST` υλοποιείται αποτελεσματικά από τις βιβλιοθήκες MPI. Ο συγκεκριμένος αλγόριθμος που χρησιμοποιείται μπορεί να ποικίλει ανάλογα με την υλοποίηση του MPI και το μέγεθος των δεδομένων που μεταδίδονται, αλλά οι κοινές στρατηγικές περιλαμβάνουν:
- Άμεση αποστολή: Η διαδικασία ρίζας στέλνει απευθείας τα δεδομένα σε κάθε άλλη διαδικασία. Αυτό είναι απλό, αλλά μπορεί να γίνει αναποτελεσματικό για μεγάλο αριθμό διαδικασιών.
- BANDCAST με βάση το δέντρο: Η διαδικασία ρίζας στέλνει τα δεδομένα σε μερικές άλλες διαδικασίες, οι οποίες στη συνέχεια προωθούν σε άλλους, σχηματίζοντας ένα δίκτυο διανομής που μοιάζει με δέντρο. Αυτό είναι γενικά πιο κλιμακωτό από την άμεση αποστολή.
- Broadcast Pipeline: Η ρίζα στέλνει σε μία διαδικασία, που στέλνει σε άλλη και ούτω καθεξής. Αυτό είναι γενικά πιο αποτελεσματικό για μεγάλα μηνύματα.
Για να μεταγλωττίσετε και να εκτελέσετε αυτόν τον κωδικό:
1. Αποθήκευση: Αποθηκεύστε τον κώδικα ως αρχείο `.cpp` (π.χ.` broadcast_example.cpp`).
2. compile: Χρησιμοποιήστε έναν μεταγλωττιστή MPI-Aware (όπως το `MPIC ++` ή `MPICC`):
`` `bash
mpic ++ broadcast_example.cpp -o broadcast_example
`` `
3. Εκτέλεση: Χρησιμοποιήστε το `mpirun` ή το` mpiexec` για να εκτελέσετε το πρόγραμμα με τον επιθυμητό αριθμό διαδικασιών:
`` `bash
mpirun -n 4./broadcast_example # Εκτελέστε με 4 διαδικασίες
`` `
έξοδος (παράδειγμα με 4 διαδικασίες):
`` `
Διαδικασία 0:Αρχικός πληθυσμός =1000
Διαδικασία 0:Αρχικός πληθυσμός =1000, προσομοιωμένος τελικός πληθυσμός =1050
Διαδικασία 1:Αρχικός πληθυσμός =1000, προσομοιωμένος τελικός πληθυσμός =1050
Διαδικασία 2:Αρχικός πληθυσμός =1000, προσομοιωμένος τελικός πληθυσμός =1050
Διαδικασία 3:Αρχικός πληθυσμός =1000, προσομοιωμένος τελικός πληθυσμός =1050
`` `
Key Takeaways:
- Το "MPI_BCAST` είναι απαραίτητο για τη διανομή δεδομένων από μία διαδικασία (ρίζα) σε όλες τις άλλες διαδικασίες σε έναν επικοινωνιακό.
- Είναι μια λειτουργία * αποκλεισμού *. Όλες οι διαδικασίες θα περιμένουν μέχρι να ολοκληρωθεί η εκπομπή.
- Συνήθως χρησιμοποιείται για τη διανομή αρχικών δεδομένων, παραμέτρων διαμόρφωσης ή άλλων πληροφοριών που απαιτούνται από όλες τις διαδικασίες για να ξεκινήσουν ή να συνεχίσουν έναν παράλληλο υπολογισμό.
- Η διαδικασία ρίζας * πρέπει * να έχει τη σωστή τιμή δεδομένων πριν από την εκπομπή.
- Όλες οι διαδικασίες * πρέπει * να καλέσετε το `mpi_bcast` (ακόμη και τη ριζική διαδικασία). Όλοι παρέχουν μια θέση μνήμης για να λάβουν * τα δεδομένα.
Αυτό το παράδειγμα παρέχει μια θεμελιώδη κατανόηση του `mpi_bcast`. Μπορείτε να το προσαρμόσετε σε πιο πολύπλοκες παράλληλες εφαρμογές όπου απαιτείται διανομή δεδομένων σε όλες τις διαδικασίες. Θυμηθείτε να επιλέξετε προσεκτικά τη διαδικασία ρίζας και να διασφαλίσετε ότι τα δεδομένα που πρόκειται να μεταδοθούν σωστά αρχικοποιούνται σε αυτή τη διαδικασία.
Πνευματικά δικαιώματα © Γνώση Υπολογιστών Όλα τα δικαιώματα κατοχυρωμένα