从MPI_Init
致电std::thread
是否安全?
int main(int argc, char** argv) {
std::thread mpi_thread([...](){
MPI_Init(...);
// All MPI calls are done by this thread.
MPI_Finalize();
});
// The main thread is doing different stuff
mpi_thread.join();
return 0;
}
答案 0 :(得分:3)
MPI standard有一个关于 MPI和主题的部分。一个重要的部分是:
初始化和完成对
MPI_FINALIZE
的调用应该在初始化MPI的同一线程上进行。我们将此主题称为主线程。呼叫应该在之后发生 所有进程线程都已完成其MPI调用,并且没有待处理的通信或I / O操作。
您的代码确实符合此要求。
MPI知道几种级别的线程支持。您的代码需要:
MPI_THREAD_FUNNELED
该过程可能是多线程的,但应用程序必须确保只有主线程才能进行MPI调用。
为了更好地衡量,您应该拨打以下内容而不是MPI_Init
:
int provided;
MPI_Init_thread(NULL, NULL, MPI_THREAD_FUNNELED, &provided);
if (provided < MPI_THREAD_FUNNELED)
MPI_Abort(MPI_COMM_WORLD, -1);
非线程兼容的MPI库必须返回provided == MPI_THREAD_SINGLE
,表示您无法在代码中正确使用此实现。
在实践中,你应该对常见的实现很好。有关不同级别的线程支持的更多信息,请参阅MPI标准中的12.4.3。随着更高级别的线程支持,您的里程可能会根据您选择的实现而有所不同。
答案 1 :(得分:1)
好的,这里有两个问题
1)代码中是否存在问题&#34;安全&#34;
是的,这里显示的代码是100%安全的,因为MPI计算发生在一个线程上。如果出现问题&#34;出错&#34;我们需要一个可重现的示例,其中包括编译器和有关集群的一些信息。有可能是由于供应商特定的配置问题,很多年前供应商会#t;祝福&#34; MPI的主要线程。
2)MPI线程安全吗? AKA你可以在第二个线程上调用MPI_RECV
吗?
这是一个更难回答的问题:thread safety of MPI send using threads created with std::async