【问题标题】:Measuring data transfer between processes in OpenMPI在 OpenMPI 中测量进程之间的数据传输
【发布时间】:2013-12-20 05:00:55
【问题描述】:

我正在使用 ubuntu 和 OpenMPI 1.4 的集群中工作。我的代码运行良好,但我想测量根进程和从节点之间发送数据的时间。

我认为我的代码没有给我正确的信息。

void invertColor_Parallel(struct image *im, int size, int rank,clock_t *sendTime)
{
     clock_t begin;

     int i,j,lum,aux,r;

     int total_pixels = (*im).ih.width * (*im).ih.height;
     int qty = total_pixels/(size-1);
     int rest = total_pixels % (size-1);
     MPI_Status status;

     //printf("\n%d\n", rank);

     if(rank == 0)
     {
        begin = MPI_Wtime();
         for(i=1; i<size; i++){
         j = i*qty - qty;
         aux = j;

         if(rest != 0 && i==size-1) {qty=qty+rest;} //para distrubuir toda la carga
         //printf("\nj: %d  qty: %d  rest: %d\n", j, qty, rest);


         MPI_Send(&aux, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD);
         MPI_Send(&qty, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD);
         MPI_Send(&(*im).array[j], qty*3, MPI_BYTE, i, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD);


         //printf("\nSending to node=%d, sender node=%d\n", i, rank);
        }
        *sendTime+=MPI_Wtime()-begin;

     }
     else
     {
        MPI_Recv(&aux, 1, MPI_INT, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD,&status);
        MPI_Recv(&qty, 1, MPI_INT, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD,&status);

        pixel *arreglo = (pixel *)calloc(qty, sizeof(pixel));
        MPI_Recv(&arreglo[0], qty*3, MPI_BYTE, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD,&status);
        //printf("Receiving node=%d, message=%d\n", rank, aux);

        for(i=0;i<qty;i++)
        {
            arreglo[i].R = 255-arreglo[i].R;
            arreglo[i].G = 255-arreglo[i].G;
            arreglo[i].B = 255-arreglo[i].B;
        }

        MPI_Send(&aux, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG+1, MPI_COMM_WORLD);
        MPI_Send(&qty, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG+2, MPI_COMM_WORLD);
        MPI_Send(&arreglo[0], qty*3, MPI_BYTE, 0, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD);

        free(arreglo);
     }


    if (rank==0){
    //printf("\nrank: %d\n", rank);
        begin=MPI_Wtime();
        for (i=1; i<size; i++) // untill all slaves have handed back the processed data
        {
            MPI_Recv(&aux, 1, MPI_INT, MPI_ANY_SOURCE, SLAVE_TO_MASTER_TAG+1, MPI_COMM_WORLD, &status);
            MPI_Recv(&qty, 1, MPI_INT, status.MPI_SOURCE, SLAVE_TO_MASTER_TAG+2, MPI_COMM_WORLD, &status);
            MPI_Recv(&(*im).array[aux], qty*3, MPI_BYTE, status.MPI_SOURCE, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD, &status);
        }
        *sendTime+=MPI_Wtime()-begin;
    }
}

void runningTime(clock_t begin, clock_t end,clock_t sendTime)
{
    double time_spent;

    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("Tiempo con Latencia: %f\n", time_spent);
    time_spent-=(double) sendTime/CLOCKS_PER_SEC;
    printf("Tiempo de envio: %f\n", time_spent);
    printf("Tiempo de latencia: %f\n\n", (double) sendTime/CLOCKS_PER_SEC);
}

int main(int argc, char *argv[])
{
    //////////time counter
    clock_t begin,sendTime=(clock_t) 0.0;


    int rank, size;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Status status;

    int op = (int)atof(argv[1]);
    struct image image2;

    if (rank==0)
    {
        loadImage(&image2, argv[2]);
    }

    //Broadcast the user's choice to all other ranks
    MPI_Bcast(&op, 1, MPI_INT, 0, MPI_COMM_WORLD);


    switch(op)
    {
        case 1:
                if (rank==0) {begin = clock();}
                MPI_Barrier(MPI_COMM_WORLD);
                invertColor_Parallel(&image2, size, rank,&sendTime);
                MPI_Barrier(MPI_COMM_WORLD);
                if (rank==0) {runningTime(begin, clock(),sendTime); printf("Se invirtieron los colores de la imagen\n\n");}
                break;
    }

    MPI_Barrier(MPI_COMM_WORLD);

    if (rank==0)
    {
        saveImage(&image2, argv[3]);
        free(image2.array);
    }

    MPI_Finalize();

    return 0;
}

我想测量进程之间的数据传输时间以及函数 ivertColor_Parallel 的整个时间。我做错了什么?

非常感谢。

【问题讨论】:

    标签: c openmpi


    【解决方案1】:

    MPI_Wtime() 返回一个双精度浮点数,它给出了自过去某个时间点以来经过的 的数量。 clock_t 是整数类型。首先,将结果从MPI_Wtime() 转换为clock_t 时,会丢失小数(亚秒)精度。其次,在将得到的 clock_t 值除以 CLOCKS_PER_SEC(在 Linux 等 POSIX 系统上等于 1000000)之后,结果始终为 0,除非两次调用 @987654327 之间的间隔超过 11 天 14 小时@。

    MPI_Wtime()的用法很简单:

    double begin = MPI_Wtime();
    ...
    double end = MPI_Wtime();
    printf("Time elapsed: %f seconds\n", end - begin);
    

    【讨论】:

    • 但是我是把begin = MPI_Wtime(); MPI_Send(&amp;(*im).array[j], qty*3, MPI_BYTE, i, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD); end = MPI_Wtime(); printf("Time elapsed: %f seconds\n", end - begin); 用那个代码获得发送数据所用的时间还是调用函数MPT_Send 所用的时间?谢谢。
    • 后者。如果这与发送数据所需的实际时间匹配,则取决于操作的模式。将MPI_Send 替换为MPI_Ssend 以强制同步模式,这样可以确保在消息传输之前MPI 调用不会返回。
    • 谢谢,现在我可以获得更准确的执行时间,并且可以准确计算加速和其他指标。
    猜你喜欢
    • 2018-02-24
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多