gpt4 book ai didi

c++11 - 通过 MPI 发送函数指针

转载 作者:行者123 更新时间:2023-12-02 06:30:18 24 4
gpt4 key购买 nike

通过 MPI 传递函数指针作为告诉另一个节点调用函数的方式是否安全?有人可能会说通过 MPI 传递任何类型的指针都是没有意义的,但我写了一些代码来验证它。

//test.cpp
#include <cstdio>
#include <iostream>
#include <mpi.h>
#include <cstring>

using namespace std;

int f1(int a){return a + 1;}
int f2(int a){return a + 2;}
int f3(int a){return a + 3;}

using F=int (*)(int);

int main(int argc, char *argv[]){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Status state;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

//test
char data[10];
if( 0 == rank ){
*(reinterpret_cast<F*>(data))=&f2;
for(int i = 1 ; i < size ; ++i)
MPI_Send(data, 8, MPI_CHAR, i, 0, MPI_COMM_WORLD);
}else{
MPI_Recv(data, 8, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &state);
F* fp = reinterpret_cast<F*>(data);
int ans = (**fp)(10);
cout << ans << endl;
}


MPI_Finalize();
return 0;
}

这是输出:

12
12
12
12
12
12
12
12
12

我通过 MVAPICH 运行它,效果很好。 但我现在不明白为什么,因为单独的地址空间意味着指针值在生成它的进程之外的任何进程中都是无用的

附言这是我的主机文件

blade11:1
blade12:1
blade13:1
blade14:1
blade15:1
blade16:1
blade17:1
blade18:2
blade19:1

然后我运行了 mpiexec -n 10 -f hostfile ./test,并使用 C++11 编译了它

最佳答案

您很幸运,因为您的集群环境是同构的,并且普通可执行文件的地址空间没有随机化。因此,所有图像都加载到相同的基地址并在内存中以相似的方式布局,因此函数在所有 MPI 等级中具有相同的虚拟地址(请注意,对于来自动态链接库的符号,这很少是真的,因为它们通常加载在随机地址)。

如果您使用不同的编译器或使用相同的编译器但使用不同的编译器选项编译源代码两次,然后让一些级别运行第一个可执行文件而其余的运行第二个可执行文件,程序肯定会崩溃。

试试这个:

$ mpicxx -std=c++11 -O0 -o test_O0 test.cpp
$ mpicxx -std=c++11 -O2 -o test_O2 test.cpp
$ mpiexec -f hostfile -n 5 ./test_O0 : -n 5 ./test_O2
12
12
12
12
<crash>

不同级别的优化导致test_O0test_O2 中的函数代码大小不同。因此,f2 将不再在所有级别中具有相同的虚拟地址。运行与等级 0 相同的可执行文件的等级将打印 12,而其余的将出现段错误。

关于c++11 - 通过 MPI 发送函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39970389/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com