我认为这是一个非常奇怪的问题: 我有这个代码: 它应该接收一个大小块和宽度的2d矩阵。 Matrix使用以下方式分配:
int **alloc2d(int n, int m) {
int i = 0;
int *data = malloc(n * m * sizeof(int));
int **array = malloc(n * sizeof(int *));
for (i = 0; i < n; i++) {
array[i] = &(data[i * m]);
}
return array;
}
所以它是一个连续的内存块。
我有以下代码:
MPI_Status st;
int worker;
for(i = 1; i < size; i++) {
MPI_Recv(&(recmat[0][0]), chunk*width, MPI_INT, MPI_ANY_SOURCE, 1,
MPI_COMM_WORLD, &st);
worker = st.MPI_SOURCE;
/* for(k = worker * chunk; k < (worker + 1) * chunk; k++){
for(j = 0; j < width; j++) {
mat[k][j] = recmat[k - worker * chunk][j];
}
}*/
}
如果代码是这样的,一切都会停止并且运行良好。 如果我取消注释该地区:
for(k = worker * chunk; k < (worker + 1) * chunk; k++){
for(j = 0; j < width; j++) {
mat[k][j] = recmat[k - worker * chunk][j];
}
}
运行此代码的线程没有停止,我找不到合理的解释。也许有人可以看到错误或问题。谢谢!
recmat分配和块计算:
int **recmat;
recmat = alloc2d(chunk,width);
int chunk;
chunk = height / size;
答案 0 :(得分:2)
很抱歉,这篇文章太长了,无法发表评论:
您发布的代码很好;例如,在它周围放置足够的代码以使其运行产生正确的结果(下面)。所以问题不在你想象的地方。
如果您看到代码锁定在您认为不应该的位置,这经常指向奇怪的内存错误或其他事情。你最好通过调试器运行它,或者像valgrind那样检查内存问题。
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int **alloc2d(int n, int m) {
int i = 0;
int *data = malloc(n * m * sizeof(int));
int **array = malloc(n * sizeof(int *));
for (i = 0; i < n; i++) {
array[i] = &(data[i * m]);
}
return array;
}
int main(int argc, char **argv) {
int rank, size;
const int height=10, width=10;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int **recmat;
int chunk;
chunk = height / size;
if (chunk*size != height) {
fprintf(stderr, "%s: number of ranks %d does not divide size %d\n",
argv[0], size, height);
MPI_Finalize();
exit(1);
}
if (rank == 0) {
int **recmat = alloc2d(chunk,width);
int **mat = alloc2d(height,width);
int worker;
int i,j,k;
MPI_Status st;
/* deal with my own submatrix */
for (k=0; k<chunk; k++) {
for (j=0; j<width; j++) {
mat[k][j] = 0;
}
}
for(i = 1; i < size; i++) {
MPI_Recv(&(recmat[0][0]), chunk*width, MPI_INT, MPI_ANY_SOURCE, 1,
MPI_COMM_WORLD, &st);
worker = st.MPI_SOURCE;
for(k = worker * chunk; k < (worker + 1) * chunk; k++){
for(j = 0; j < width; j++) {
mat[k][j] = recmat[k - worker * chunk][j];
}
}
}
free(&(recmat[0][0]));
free(recmat);
printf("Rank 0: mat is \n");
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
printf("%2d ", mat[i][j]);
}
printf("\n");
}
free(&(mat[0][0]));
free(mat);
} else {
int **sendmat = alloc2d(chunk,width);
for (int i=0; i<chunk; i++)
for (int j=0; j<width; j++)
sendmat[i][j] = rank;
MPI_Send(&(sendmat[0][0]), chunk*width, MPI_INT, 0, 1, MPI_COMM_WORLD);
free(&(sendmat[0][0]));
free(sendmat);
}
MPI_Finalize();
return 0;
}
答案 1 :(得分:0)
我的代码中有很多错误和错误,甚至不值得一提,我很抱歉这个无用的问题...
答案 2 :(得分:0)
这也是一个较长的评论。如果您首先探测消息,则可以防止接收数据的双重复制,然后使用状态中的等级直接将消息内容接收到大矩阵中:
for(i = 1; i < size; i++) {
MPI_Probe(MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &st);
worker = st.MPI_SOURCE;
MPI_Recv(&(mat[worker*chunk][0]), chunk*width, MPI_INT,
worker, 1, MPI_COMM_WORLD, &st);
}
更少的代码,应该更快地工作。