2013-12-20 5 views
0

Я работаю в кластере с ubuntu и OpenMPI 1.4. Мой код работает хорошо, но я хотел бы определить время, необходимое для отправки данных между корневым процессом и подчиненными узлами.Измерение передачи данных между процессами в OpenMPI

Я думаю, что мой код не дает мне правильной информации.

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. Что я делаю не так?.

спасибо.

ответ

0

возвращает число с плавающей запятой двойной точности, которое дает сумму секунд прошло с того или иного момента в прошлом. clock_t - целочисленный тип. Во-первых, вы теряете дробную (подсевую) точность при преобразовании результата из MPI_Wtime() в clock_t. Во-вторых, после того, как вы разделите полученное значение clock_t на CLOCKS_PER_SEC (равное 1000000 на системах POSIX, таких как Linux), результат всегда будет равным 0, если между двумя вызовами не будет больше 11 дней и 14 часов до MPI_Wtime().

MPI_Wtime() использование так просто, как:

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

Но я положил 'начать = MPI_Wtime(); MPI_Send (& (* im) .array [j], qty * 3, MPI_BYTE, i, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD); end = MPI_Wtime(); printf («Истекшее время:% f секунд \ n», конец - начало); «С этим кодом я получаю время, затраченное на отправку данных или время, которое требуется для вызова функции MPT_Send ?. Спасибо. –

+0

Последний. Если это соответствует фактическому времени, которое требуется для отправки данных, или нет, зависит от режима работы. Замените «MPI_Send» на «MPI_Ssend» для принудительного синхронного режима, который гарантирует, что вызов MPI не будет возвращен до передачи сообщения. –

+0

Спасибо, теперь я могу получить более точное время выполнения и может быстро вычислить ускорение и другие показатели. –

Смежные вопросы