next up previous
Siguiente: Bibliografía Subir: Implementación de un cluster Anterior: Conclusiones

Ejemplo de código paralelo MPI para el cluster OpenMosix

Código paralelo para el cálculo del área bajo la curva de una función f(x) [*].

[fontfamily=courier,fontshape=it,fontsize=\small,baselinestretch=0.6]
    /**
    * Este programa calcula el área bajo la curva del polinomio
    * f(x)= Y = 10.5 + 1.2x + 0.8x^2 - 2.25x^3 + 0.5x^4 con límite
    * inferior 0 y límite superior 9.5 haciendo uso de la librería
    * MPI para código paralelo. La función f(x) puede ser cambiada
    * en f_de_x(), ver más abajo.
    * Código modificado de la fuente:
    * http://www.cc.ku.edu/~grobe/docs/intro-MPI-C.shtml {Enero 2006}
    **/

   #include <stdio.h>
   #include <math.h>
   #include <mpi.h>

   #define PI 3.1415926535
   #define LIM_INF 0.0 /*Limite Inferior de la Integral*/
   #define LIM_SUP 9.5 /*Limite Superior de la Integral*/

   double f_de_x(double x);
   /*En el cuerpo de esta función puedes cambiar el calculo para f(x)*/

   main(int argc, char **argv)
   {
      int my_id, root_process, num_procs, ierr, num_intervals, i;
      double rect_width, area, sum, x_middle, partial_sum;
      MPI_Status status;

      /* 0 es el proceso raíz. */
      root_process = 0;

      /* Replicar el proceso para crear procesos paralelos. */
      ierr = MPI_Init(&argc, &argv);

      /* Encuentra MI ID de proceso y cuantos procesos fueron iniciados. */
      ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
      ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
      if(my_id == root_process) {

         /*Modificar el código de las siguientes líneas si se quiere
          *preguntar al usuario cuantos procesos iniciar.
          *printf("Please enter the number of intervals to interpolate: ");
         scanf("%i", &num_intervals);*/
        num_intervals = 150000000;
        printf("Integrando la función \
        Y = 10.5 + 1.2x + 0.8x^2 - 2.25x^3 + 0.5x^4 \
        en %d intervalos...\n",num_intervals);
        printf("Límite Inferior: %f\n",LIM_INF);
        printf("Límite Superior: %f\n\n",LIM_SUP);
      }

      /* Se envía un mensaje a todos los subprocesos del número de
       * intervalos. */
      ierr = MPI_Bcast(&num_intervals, 1, MPI_INT, root_process,
            MPI_COMM_WORLD);

      /* cálculo de la base del rectángulo, y ... */

      rect_width = (LIM_SUP - LIM_INF) / num_intervals;

      /* se calcula la suma de las áreas de los rectángulos de las cuales el
       * subproceso es responsable. */
      partial_sum = 0;
      for(i = my_id + 1; i <num_intervals + 1; i += num_procs) {
         x_middle = (i - 0.5) * rect_width;
         area =  f_de_x(x_middle) * rect_width;
         partial_sum = partial_sum + area;
      }
      printf("proc %i computes: %f\n", my_id, partial_sum);

      /* Finalmente las sumas parciales son recogidas en la variable "sum" */
      ierr = MPI_Reduce(&partial_sum, &sum, 1, MPI_DOUBLE,
            MPI_SUM, root_process, MPI_COMM_WORLD);

      /* Si soy el proceso raíz, imprimo el resultado */
      if(my_id == root_process) {
         printf("The integral is %f\n", sum);
      }

      /* finaliza el proceso. */
      ierr = MPI_Finalize();
   }

double f_de_x(double x)
{
    double punto = 0.0, valor = 0.0;
    double poli[]={10.5,1.2,0.8,-2.25,0.5};
    int  i = 0;

    punto = x;
    for(i=0;i<5;i++)
      valor += poli[i]*pow(punto,i);
    return valor;

/*El usuario puede definir otras funciones, Ejemplos:
1) return sin(x);

2) return cos(x);

3) return x*x;

4) return x/2;
*/
}





Licencia: Creative Commons

Reconocimiento-NoComercial 2.5 México

JoseCC & SuperBenja, 2006-06-08