У меня небольшая проблема с упражнением «Сортировка слиянием с MPI». если я компилирую с использованием «mpirun -np 2 --allow-run-as- root a.out», он работает правильно, но если я компилирую с использованием «mpirun -np 4 --allow-run-as- root a .out "я получил странный вектор: 1 1 2 4 7 8 11 15 0 4 6 6 8 8 10 10, и он упорядочен до половины. вы можете помочь мне понять почему? спасибо
#include "mpi.h"
using namespace std;
#include <iostream>
#include <cmath>
//void merge(int *, int *, int);
#define n 16
void mergeSort(int *recdata, int buf)
{
int meta = buf / 2;
if (meta > 0)
{
mergeSort(recdata, meta); //analizzo prima meta' dell'array
mergeSort(recdata + meta, buf - meta); //analizzo seconda meta' dell'array
//classico merge sort
int *tmp = new int[buf];
int i = 0;
int k = 0;
int j = meta;
while (i < meta && j < buf)
{
if (recdata[i] < recdata[j])
{
tmp[k] = recdata[i];
i++;
}
else
{
tmp[k] = recdata[j];
j++;
}
k++;
}
while (i < meta)
{
tmp[k] = recdata[i];
k++;
i++;
}
while (j < buf)
{
tmp[k] = recdata[j];
k++;
j++;
}
for (i = 0; i < buf; i++)
recdata[i] = tmp[i];
delete[] tmp;
}
}
int main(int argc, char *argv[])
{
int myid;
int numprocs;
int buf;
double timer_start;
double timer_end;
MPI_Request req;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
int *data;
buf = n / numprocs; //buf e' il numero di elementi cha avra' ogni processo
if (myid == 0)
{
data = new int[n];
cout << endl
<< "Array disordinato: ";
srand(time(NULL));
for (int i = 0; i < n; i++)
{
data[i] = rand() % n;
cout << data[i] << " ";
}
timer_start = MPI_Wtime();
cout << endl
<< endl;
}
int *recdata = new int[n]; //array vuoto che mi permette di conservare tutti i dati divisi sui vari processi
// prendo struttura dati e la mando a tutti i processi
// data contiene tutti i numeri, buf e' la quantita' di numeri da mandare
//int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
// void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
// data e' l'array originale che contine numeri disordinati, buf e' il numero di elementi che ogni vettore riceve
// recdata e' il nuovo array che deve contenere i numeri ricevuti
MPI_Scatter(data, buf, MPI_INT, recdata, buf, MPI_INT, 0, MPI_COMM_WORLD);
//local sort
mergeSort(recdata, buf);
bool u = true;
while (u)
{
if (myid % 2 == 0)
{
//mando il max
int min;
// mando ricevo
MPI_Sendrecv(&recdata[buf - 1], 1, MPI_INT, myid + 1, 0, &min, 1, MPI_INT, myid + 1, 0, MPI_COMM_WORLD, &status);
//MPI_Recv(&min, 1, MPI_INT, myid + 1, 0, MPI_COMM_WORLD, &status);
if (min < recdata[buf - 1])
{
recdata[buf - 1] = min;
mergeSort(recdata, buf);
}
else
u = false;
}
else
{
//mando il minimo
int max;
// mando ricevo
MPI_Sendrecv(&recdata[0], 1, MPI_INT, myid - 1, 0, &max, 1, MPI_INT, myid - 1, 0, MPI_COMM_WORLD, &status);
if (max > recdata[0])
{
recdata[0] = max;
mergeSort(recdata, buf);
}
else
u = false;
}
}
/*int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)*/
MPI_Gather(recdata, buf, MPI_INT, data, buf, MPI_INT, 0, MPI_COMM_WORLD);
if (myid == 0)
{
cout << endl
<< "Array ordinato: " << endl;
for (int i = 0; i < n; i++)
cout << data[i] << " ";
cout << endl
<< endl;
timer_end = MPI_Wtime();
cout << endl
<< endl
<< "Time: " << timer_end - timer_start << endl
<< endl;
}
MPI_Finalize();
return 0;
}