为什么使用MPI_Bcast和-O3编译器标志会出现堆栈粉碎错误,但是在没有-O3的情况下一切正常?]

问题描述 投票:1回答:1
我对MPI还是很陌生,因此很简单,很抱歉。

我有一两个月前的一些代码可以正常工作,但是我决定回去修改它。 (它是在我刚入门时编写的,它不是性能至关重要的部分。)代码基本上是在一个进程上生成一个随机图,然后与所有其他进程共享结果。摘自婴儿的第一步版摘录:

unsigned int *graph; if (commrank == 0) { graph = gengraph(params); //allocates graph memory in function if (commsize > 1) { for (int k=1; k<commsize; k++) MPI_Send(graph, n*n, MPI_UNSIGNED, k, 0, MPI_COMM_WORLD); } } else { MPI_Status recvStatus; graph = malloc(sizeof(unsigned int)*n*n); MPI_Recv(graph, n*n, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD, &recvStatus); }

虽然显然很幼稚,但在我选择回去以我认为合适的方式进行操作之前,这种方法工作了好一阵子:

if (commrank == 0) { graph = gengraph(params); MPI_Bcast(graph, n*n, MPI_UNSIGNED, 0, MPI_COMM_WORLD); } else { graph = malloc(sizeof(unsigned int)*n*n); MPI_Bcast(graph, n*n, MPI_UNSIGNED, 0, MPI_COMM_WORLD); }

问题是,当我使用-O3优化进行编译时,在第二个版本中不断出现“堆栈粉碎”错误时,尽管在未优化的情况下编译仍然可以正常工作。请注意,我已经多次检查了图形分配函数并对其进行了调试,这似乎很好。我还调试了第二个版本,它似乎可以正常工作。稍后当我尝试释放图形内存时发生崩溃。 (请注意,这不是双重释放错误,再次,它在幼稚的实现中运行良好,并且存在一段时间。)

最后的皱纹:如果我不是使用recvStatus变量而是使用MPI_STATUS_IGNORE,则

first

版本也会失败。而且,这仅在-O3下失败。任何想法都将不胜感激。如果有帮助,我将在gcc 7.5.0之上使用mpicc,但我想我正在做一些愚蠢的事情,而不是遇到编译器问题。

我对MPI还是陌生的,如果这很简单,请您道歉。我有一两个月前的代码可以正常工作,但是我决定回去修改它。 (它是在我刚刚...

c mpi
1个回答
0
投票
根据@ hristo-iliev的建议,我将mpicc编译器更改为Clang并使用了Address Sanitizer,并在随后的MPI调用中发现了错误(计数大小错误的recv)。这导致了不确定的行为。值得注意的是,地址清理器可以很清楚地指出错误的位置,而valgrind仅给出了相当不透明的指示,表明MPI中正在发生某些事情(同样,它总是如此)。
© www.soinside.com 2019 - 2024. All rights reserved.