int main (int argc, char *argv[]) { int proc_id, n_procs, limite_inf, limite_sup, n_dentro, i; double pi_local, pi_total, x, y, z, error, start_time, end_time; n_dentro = 0; /* Inicio MPI */ MPI_Init(&argc, &argv); /* Obtener rango y tamaño del comm_world */ MPI_Comm_rank(MPI_COMM_WORLD, &proc_id); MPI_Comm_size(MPI_COMM_WORLD, &n_procs); /* Unicamente el maestro imprime en pantalla los datos iniciales */ if (proc_id == MASTER) { system("clear"); printf("## Implementación de Montecarlo para el cálculo de PI\n\n"); obtener_info_sist(); printf("## Total de procesadores: %d\n", n_procs); printf("## Comienzo del programa con %d tiradas.\n\n", TIRADAS); } /* Procedimiento: Obtener un numero aleatorio, calcular por Pitágoras si está dentro del círculo, y si cumple, incrementar la cuenta... */ srand(time(NULL)); if (proc_id == MASTER) start_time = MPI_Wtime(); for (i = 1; i <= TIRADAS; ++i) { x = rand()/(double)RAND_MAX; y = rand()/(double)RAND_MAX; z = pow(x, 2) + pow(y, 2); if (z <= 1.0) n_dentro+=1; } /*... Luego calcular PI con la cuenta dada... */ pi_local = 4.0 * (double)n_dentro/(double)TIRADAS; /* Actualizar el resultado, suma de todos los cálculos... */ MPI_Reduce(&pi_local, &pi_total, 1, MPI_DOUBLE, MPI_SUM, MASTER, MPI_COMM_WORLD); if (proc_id != MASTER) printf("~ Se ha enviado el valor de PI: %g, del proceso: %d\n", pi_local, proc_id); MPI_Barrier(MPI_COMM_WORLD); /* Unicamente maestro: calcular la media, error, imprimir resultados. */ if (proc_id == MASTER) { pi_total = pi_total / n_procs; error = fabs((pi_total - PI)/PI) * 100; end_time = MPI_Wtime(); printf("## Valor real: %11.10f\n", PI); printf("## Valor calculado: %11.10f\n", pi_total); printf("## Error: %10.8f\n", error); printf("## Tiempo empleado: %10.8f\n\n", end_time - start_time); } /* Terminar espacio MPI */ MPI_Finalize(); return 0; }
int main(int argc, char **argv) { int proc_id, n_procs, i, envios; int buffer0[SIZE0], buffer1[SIZE1], buffer2[SIZE2], buffer3[SIZE3], buffer4[SIZE4]; int buffer5[SIZE5], buffer6[SIZE6], buffer7[SIZE7], buffer8[SIZE8], buffer9[SIZE9]; MPI_Status estado; /* Inicio del entorno MPI */ MPI_Init (&argc, &argv); /* Obtener rango y tamaño del comm_world */ MPI_Comm_rank(MPI_COMM_WORLD, &proc_id); MPI_Comm_size(MPI_COMM_WORLD, &n_procs); if (n_procs != 2) { printf("## Este programa utiliza 2 procesos\n"); exit(EXIT_FAILURE); } /* Sincronizar a todos los procesos */ MPI_Barrier(MPI_COMM_WORLD); /* Unicamente el maestro imprime en pantalla los datos iniciales */ if (proc_id == MASTER) { system("clear"); printf("## Cálculo de RTT / Envío Maestro-Esclavo\n\n"); printf("## Total de procesadores: %d\n", n_procs); obtener_info_sist(); /* Leer de stdin la cantidad de envíos a hacer */ do { printf("%s", MENU_ENVIOS); scanf("%d", &envios); } while ((envios != 1) && (envios != 2) && (envios != 3)); switch (envios) { case 1: envios = 100; break; case 2: envios = 1000; break; case 3: envios = 10000; break; default: break; } /* Enviar dato a los procesos */ MPI_Send(&envios, sizeof(envios), MPI_INT, ESCLAVO, 0, MPI_COMM_WORLD); printf("## Comienzo del envío con: %d envios;\n", envios); printf("## Tamaño de datos:\n"); printf("## \tSIZE0 = %d\n", SIZE0); printf("## \tSIZE1 = %d\n", SIZE1); printf("## \tSIZE2 = %d\n", SIZE2); printf("## \tSIZE3 = %d\n", SIZE3); printf("## \tSIZE4 = %d\n", SIZE4); printf("## \tSIZE5 = %d\n", SIZE5); printf("## \tSIZE6 = %d\n", SIZE6); printf("## \tSIZE7 = %d\n", SIZE7); printf("## \tSIZE8 = %d\n", SIZE8); printf("## \tSIZE9 = %d\n", SIZE9); printf("\n"); } MPI_Barrier(MPI_COMM_WORLD); if (proc_id == MASTER) { printf("## | tam (b) | envios | t_total (seg) | t/envio (s) | kB/s |\n"); printf("## |---------|--------|---------------|--------------|------------|\n"); master_func(SIZE0, envios, estado); master_func(SIZE1, envios, estado); master_func(SIZE2, envios, estado); master_func(SIZE3, envios, estado); master_func(SIZE4, envios, estado); master_func(SIZE5, envios, estado); master_func(SIZE6, envios, estado); master_func(SIZE7, envios, estado); master_func(SIZE8, envios, estado); master_func(SIZE9, envios, estado); printf("## |_________|________|_______________|______________|____________|\n"); } else { /* Primero, recibir del maestro el dato de envios */ MPI_Recv(&envios, sizeof(envios), MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); /* Ahora realizar el recibo y envío con esa cantidad */ for(i = 0; i < envios; ++i) { MPI_Recv(buffer0, SIZE0, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer0[0] += 1; MPI_Send(buffer0, SIZE0, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer1, SIZE1, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer1[0] += 1; MPI_Send(buffer1, SIZE1, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer2, SIZE2, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer2[0] += 1; MPI_Send(buffer2, SIZE2, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer3, SIZE3, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer3[0] += 1; MPI_Send(buffer3, SIZE3, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer4, SIZE4, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer4[0] += 1; MPI_Send(buffer4, SIZE4, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer5, SIZE5, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer5[0] += 1; MPI_Send(buffer5, SIZE5, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer6, SIZE6, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer6[0] += 1; MPI_Send(buffer6, SIZE6, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer7, SIZE7, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer7[0] += 1; MPI_Send(buffer7, SIZE7, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer8, SIZE8, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer8[0] += 1; MPI_Send(buffer8, SIZE8, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } for(i = 0; i < envios; ++i) { MPI_Recv(buffer9, SIZE9, MPI_INT, MASTER, 0, MPI_COMM_WORLD, &estado); buffer9[0] += 1; MPI_Send(buffer9, SIZE9, MPI_INT, MASTER, 0, MPI_COMM_WORLD); } } /* Terminar entorno */ MPI_Finalize (); exit(EXIT_SUCCESS); }