我有一个MPI程序,它过度订阅/过度使用其处理器.那就是:进程多于处理器.
但是,在给定时间内,这些进程中只有少数是活动的,因此不应该争用计算资源.
但是,就像来自海底总动员的一群海鸥一样,当这些过程等待通信时,他们都在忙着循环,问"我的?我的?我的?"?
我正在使用英特尔MPI和OpenMPI(适用于不同的机器).我怎样才能说服他们既没有繁忙的循环?
我的快速而肮脏的解决方案是MPI_Iprobe
在带有sleep命令的循环中使用(参见此处).
在大量内核上调试我的程序,我遇到了非常奇怪的错误insufficient virtual memory
.我的调查导致代码的和平,主机向每个从机发送小消息.然后我写了一个小程序,其中1个master只发送10个整数,MPI_SEND
所有从属接收它MPI_RECV
./proc/self/status
前后文件的比较MPI_SEND
表明,内存大小之间的差异是巨大的!最有趣的事情(崩溃我的程序)是,这个内存不会释放后MPI_Send
仍然占用大量空间.
有任何想法吗?
System memory usage before MPI_Send, rank: 0
Name: test_send_size
State: R (running)
Pid: 7825
Groups: 2840
VmPeak: 251400 kB
VmSize: 186628 kB
VmLck: 72 kB
VmHWM: 4068 kB
VmRSS: 4068 kB
VmData: 71076 kB
VmStk: 92 kB
VmExe: 604 kB
VmLib: 6588 kB
VmPTE: 148 kB
VmSwap: 0 kB
Threads: 3
System memory usage after MPI_Send, rank 0
Name: test_send_size
State: R (running)
Pid: …
Run Code Online (Sandbox Code Playgroud) 我正在编写一些计算成本高但高度可并行化的代码。并行化后,我打算在 HPC 上运行它,但是为了将运行时间缩短到一周内,问题需要随着处理器数量的增加而很好地扩展。
下面是我试图实现的一个简单而荒谬的例子,它足够简洁,可以编译和演示我的问题;
#include <iostream>
#include <ctime>
#include "mpi.h"
using namespace std;
double int_theta(double E){
double result = 0;
for (int k = 0; k < 20000; k++)
result += E*k;
return result;
}
int main()
{
int n = 3500000;
int counter = 0;
time_t timer;
int start_time = time(&timer);
int myid, numprocs;
int k;
double integrate, result;
double end = 0.5;
double start = -2.;
double E;
double factor = (end - start)/(n*1.);
integrate = 0;
MPI_Init(NULL,NULL); …
Run Code Online (Sandbox Code Playgroud) 我有一个很大的代码,它因以下错误而崩溃:
Fatal error in PMPI_Comm_split: Other MPI error, error stack:
PMPI_Comm_split(532)................: MPI_Comm_split(comm=0xc4027cf0, color=0, key=0, new_comm=0x7ffdb50f2bd0) failed
PMPI_Comm_split(508)................: fail failed
MPIR_Comm_split_impl(260)...........: fail failed
MPIR_Get_contextid_sparse_group(676): Too many communicators (0/16384 free on this process; ignore_id=0)
Fatal error in PMPI_Comm_split: Other MPI error, error stack:
PMPI_Comm_split(532)................: MPI_Comm_split(comm=0xc401bcf1, color=1, key=0, new_comm=0x7ffed5aa4fd0) failed
PMPI_Comm_split(508)................: fail failed
MPIR_Comm_split_impl(260)...........: fail failed
MPIR_Get_contextid_sparse_group(676): Too many communicators (0/16384 free on this process; ignore_id=0)
Fatal error in PMPI_Comm_split: Other MPI error, error stack:
PMPI_Comm_split(532)................: MPI_Comm_split(comm=0xc4027ce9, color=0, key=0, new_comm=0x7ffe37e477d0) failed
PMPI_Comm_split(508)................: fail …
Run Code Online (Sandbox Code Playgroud) 我有一个使用openmpi编译并运行的代码。最近,我想使用Intel MPI运行相同的代码。但是我的代码无法正常工作。我深入研究代码,发现MPI_Send在两种实现中的行为都不同。
我从其他论坛获得了使用MPI_Isend而不是来自其他论坛的MPi_Send的建议。但这需要大量的工作来修改代码。英特尔MPI中是否有任何变通办法,使其能够像在OpenMPI中那样工作。可能是某些标志或缓冲区增加或其他。预先感谢您的回答。
int main(int argc, char **argv) {
int numRanks;
int rank;
char cmd[] = "Hello world";
MPI_Status status;
MPI_Init (&argc, &argv);
MPI_Comm_size (MPI_COMM_WORLD, &numRanks);
MPI_Comm_rank (MPI_COMM_WORLD, &rank);
if(rank == 0) {
for (int i=0; i< numRanks; i++) {
printf("Calling MPI_Send() from rank %d to %d\n", rank, i);
MPI_Send(&cmd,sizeof(cmd),MPI_CHAR,i,MPI_TAG,MPI_COMM_WORLD);
printf("Returned from MPI_Send()\n");
}
}
MPI_Recv(&cmd,sizeof(cmd),MPI_CHAR,0,MPI_TAG,MPI_COMM_WORLD,&status);
printf("%d receieved from 0 %s\n", rank, cmd);
MPI_Finalize();
}
Run Code Online (Sandbox Code Playgroud)
# mpirun --allow-run-as-root -n 2 helloworld_openmpi
Calling MPI_Send() from rank 0 to 0
Returned …
Run Code Online (Sandbox Code Playgroud)