I have a serial C ++ program that I want to parallelize. I know the basics of the MPI, MPI_Send, MPI_Recvetc. Basically, I have a data generation algorithm that works much faster than a data processing algorithm. They are currently being run sequentially, but I thought that starting data generation in the root process, processing the data is done on slave processes and sending a message from the root to the slave containing the data to be processed. Thus, each slave processes the data set and then waits for its next data set.
The problem is that after the root process is executed with data generation, the program freezes because the slaves wait more.
This is an example of a problem:
#include "mpi.h"
#include <cassert>
#include <cstdio>
class Generator {
public:
Generator(int min, int max) : value(min - 1), max(max) {}
bool NextValue() {
++value;
return value < max;
}
int Value() { return value; }
private:
int value, max;
Generator() {}
Generator(const Generator &other) {}
Generator &operator=(const Generator &other) { return *this; }
};
long fibonnaci(int n) {
assert(n > 0);
if (n == 1 || n == 2) return 1;
return fibonnaci(n-1) + fibonnaci(n-2);
}
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int rank, num_procs;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
if (rank == 0) {
Generator generator(1, 2 * num_procs);
int proc = 1;
while (generator.NextValue()) {
int value = generator.Value();
MPI_Send(&value, 1, MPI_INT, proc, 73, MPI_COMM_WORLD);
printf("** Sent %d to process %d.\n", value, proc);
proc = proc % (num_procs - 1) + 1;
}
} else {
while (true) {
int value;
MPI_Status status;
MPI_Recv(&value, 1, MPI_INT, 0, 73, MPI_COMM_WORLD, &status);
printf("** Received %d from process %d.\n", value, status.MPI_SOURCE);
printf("Process %d computed %d.\n", rank, fibonnaci(2 * (value + 10)));
}
}
MPI_Finalize();
return 0;
}
Obviously, not all of the above is “good practice,” but getting a point is enough.
If I delete while(true)from the slave processes, the program will exit when they exit each slave. I would like the program to exit only after the root process has completed its work, and all subordinates processed everything that was sent.
If I knew how many datasets will be generated, I can have many processes and everything will work fine, but this is not the case.
? - API, ? ? MPI_Isend MPI_IRecv ? MPI, .