【发布时间】:2014-04-10 03:04:47
【问题描述】:
最近,我开始在集群上工作以加快工作速度。目前我的工作是使用不同大小的输入数据来分析代码。以前我在每个输入文件的for 循环中这样做。在集群上,我使用 MPI 将每个不同的输入作为不同的进程运行程序。
MPI 脚本的源代码可以在下面找到。它运行不同的进程,还有一个“服务器”进程写出结果,以避免两个进程同时写出输出文件的情况。由于代码现在是结构化的,如果所有进程都按时结束,我只能访问输出。这是一个问题,因为我试图将我的工作的 walltime 保持在尽可能低的时间以使工作快速启动(集群总是满的,所以如果我需要太多资源,就很难开始工作)。所以有时我的工作会过早地被调度程序中断。
我的想法是在服务器进程中添加一个计时器,如果当前的 walltime 接近最大值(在下面的代码中为两分钟),则关闭文件流。这样,至少我不会丢失已经收集到的数据。然而,这将不起作用,因为计时器仅在服务器接收到新数据时才会更新。 应避免仅在服务器接收到新数据时打开文件,因为我更喜欢每次提交作业时都从空输出文件开始。还有哪些其他选项可以确保我不会丢失已收集的输出?
#include <mpi.h>
#define RES 1
int main(int argc, char *argv[]){
int nprocs, myid, server, ndone;
double WallTime;
struct timeval start, end;
double countTime, res[4];
FILE *fpt;
WallTime = 1*60+59;
MPI_Comm world;
MPI_Group world_group;
MPI_Status status;
MPI_Init(&argc, &argv);
world = MPI_COMM_WORLD;
MPI_Comm_size(world,&nprocs);
MPI_Comm_rank(world,&myid);
server = nprocs-1; /* last proc is server */
MPI_Comm_group(world, &world_group);
if(myid == server){ /* I store the output */
ndone = 0;
fpt = fopen(argv[2],"wt");
gettimeofday(&start, NULL);
do{
MPI_Recv(res, 4, MPI_DOUBLE, MPI_ANY_SOURCE, RES, world, &status);
fprintf(fpt,"%d\t%10.7f\t%10.7f\t%ld\n", (int) res[0], res[1], res[2], (long int) res[3]);
gettimeofday(&end, NULL);
countTime = (end.tv_sec+(end.tv_usec)*1.e-6)-(start.tv_sec+(start.tv_usec)*1.e-6);
ndone++;
} while (ndone < (nprocs-1) && countTime < WallTime);
fclose(fpt);
} else if(myid<(nprocs-1)){
do sth with data according to myid ...
MPI_Send(res, 4, MPI_DOUBLE, server, RES, world);
}
MPI_Finalize();
}
【问题讨论】: