c++ - MPI程序的段错误

标签 c++ multithreading segmentation-fault mpi

我正在用 C++ 编写一个使用 MPI 的程序。我的代码的简化版本是

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <mpi.h>
#define RNumber 3000000 //Number of loops to go

using namespace std;

class LObject {
        /*Something here*/
    public:
        void FillArray(long * RawT){
            /*Does something*/
            for (int i = 0; i < RNumber; i++){
                RawT[i] = i;
            }
        }
};

int main() {
    int     my_rank;
    int     comm_sz;
    MPI_Init(NULL, NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);

    LObject System;

    long rawT[RNumber];
    long * Times = NULL;
    if (my_rank == 0) Times = (long*) malloc(comm_sz*RNumber*sizeof(long));

    System.FillArray(rawT);

    if (my_rank == 0) {
        MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber,
                MPI_LONG, 0, MPI_COMM_WORLD);
    }
    else {
        MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber,
                MPI_LONG, 0, MPI_COMM_WORLD);
    }

    MPI_Finalize();
    return 0;
};

程序编译正常,但在执行时给出了段错误。消息是

=================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
=================================================================================
APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)

当我减少 RNumber 时,程序工作正常。也许有人可以解释到底出了什么问题?我是否试图为数组分配太多空间?如果是这样的话,这个问题是否可以通过将结果存储在文件而不是数组中来解决?

如果可能的话,请您对我做错的事情给出广泛的评论。

感谢您付出的时间和精力!

最佳答案

几个可能的问题:

long rawT[RNumber];

要放入堆栈的数组相当大。堆栈大小通常有限制(尤其是在多线程程序中),典型大小为一或两兆字节。 std::vector<long> 你会过得更好在这里。

Times = (long*) malloc(comm_sz*RNumber*sizeof(long));

您应该检查内存分配是否成功。或者更好,使用 std::vector<long>这里也一样(这也将修复您的内存泄漏)。

if (my_rank == 0) {
    // do stuff
} else {
    // do exactly the same stuff
}

我猜 else block 应该做一些不同的事情;特别是,不涉及 Times 的东西,因为除非 my_rank == 0 否则它为 null .

更新:要使用 vector 而不是原始数组,只需将其初始化为您想要的大小,然后使用指向您将使用(指向)数组的第一个元素的指针:

std::vector<long> rawT(RNumber);
System.FillArray(&rawT[0]);

std::vector<long> Times(comm_sz*RNumber);
MPI_Gather(&rawT[0], RNumber, MPI_LONG, &Times[0], RNumber,
           MPI_LONG, 0, MPI_COMM_WORLD);

请注意,如果您调整 vector 的大小,指针将失效(尽管如果您只是将其用作数组的替代品,则不需要这样做)。

关于c++ - MPI程序的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8047575/

相关文章:

c++ - 以编程方式修改/创建 vcproj 文件

c# - 来自不同线程的 WPF 和 NotifyPropertyChanged

c# - 如何使用 ImmutableList<> 而不是 List<> 来获得线程安全?

c - 为什么这个函数会导致段错误?

c++ - 实体组件系统和共享公共(public)基类型的多个组件

c++ - 在 C++ 的构造函数中将字符串文字分配给成员 const char* 变量时会发生什么?

c++ - 虚继承与多态 : Is the cereal library messing with object layout?

C#如何杀死父线程

c - 在 C 中没有出现段错误

c - C 链表新手的段错误帮助