繁体   English   中英

为什么我使用 MPI_Bcast 和 -O3 编译器标志会收到堆栈粉碎错误,但没有 -O3 一切正常?

[英]Why do I get a stack smashing error using MPI_Bcast and -O3 compiler flag, but everything works without -O3?

我对 MPI 很陌生,如果这很简单,我很抱歉。

我有一两个月前的一些代码一直运行良好,但我决定返回 go 并对其进行修改。 (它是我刚开始时写的,它不是性能关键部分。)代码基本上在一个进程上生成一个随机图,然后与所有其他进程共享结果。 婴儿的第一步版本的摘录如下:

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);
}

虽然显然很天真,但在我选择 go 并以我认为正确的方式执行之前,这工作了一段时间:

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 优化进行编译时,我在第二个版本中不断出现“堆栈粉碎”错误,尽管在未优化编译时它工作正常。 请注意,我已经多次检查了图形分配 function 并对其进行了调试,看起来还不错。 我还调试了第二个版本,它似乎工作正常。 稍后当我尝试释放图形 memory 时发生崩溃。 (请注意,这不是双重释放错误,而且,它在幼稚的实现中也能正常工作,并且已经有一段时间了。)

最后一个问题:如果我没有使用recvStatus变量,而是使用MPI_STATUS_IGNORE第一个版本也会失败。 而且,这仅在 -O3 时失败。

任何想法将不胜感激。 如果有任何帮助,我在 gcc 7.5.0 之上使用 mpicc,但我想我在做一些愚蠢的事情而不是遇到编译器问题。

根据@hristo-iliev 的建议,我将 mpicc 编译器更改为 Clang 并使用了 Address Sanitizer,并在随后的 MPI 调用中发现了错误(recv 计数大小错误)。 这导致了未定义的行为。 值得注意的是,地址清理程序非常清楚地指出了错误的位置,而 valgrind 仅给出了相当不透明的指示,表明 MPI 中正在发生某些事情(好吧,它总是如此)。

为此向 StackOverflow 社区道歉,因为上面的代码不是罪魁祸首(并不完全令人惊讶)。 由于草率,这只是一些标准的未定义行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM