program openmp !=========================================================================! ! OpenMP es un paradigma de programacion paralela de memoria compartida ! ! Se insertan secciones de codigo paralelo entre las directivas: ! ! !$OMP PARALLEL ! ! ..... ! ! !$OMP END PARALLEL ! ! Se compila con la opcion: -fopenmp ! !=========================================================================! use omp_lib integer :: nthreads, id integer :: temp,suma integer :: n integer,dimension(10) :: vector,vector1 !--- vars para la integracion ----- integer :: nx real :: delta_x , x, xo, x1, integral !=========== paralelizacion segun el id del thread =================== ! Cada thread tiene un numero de id, el thread 0 es el padre (root) ! !===================================================================== print *, "-------- THREADS Y SECCIONES PARALELAS EN OPENMP ----------" !$OMP PARALLEL PRIVATE(nthreads) id=omp_get_thread_num() ! obtengo el thread id de turno if (id == 0 ) then nthreads=omp_get_num_threads() ! Para el thread root (0), obtengo la cantidad de threads print*, "Soy thread root (0). el nro de threads es: ",nthreads else print*, "Hola mi thread id: ", id end if !print*, "Hola mi thread id: ", id !$OMP END PARALLEL print *,"----------------------------------------------------------" print *, n = 10 !============ ejemplo de parelizacion de un loop ======================== ! En este ejemplo se divide el rango del loop`entre la cantidad de ! ! thrads que hay, para cada subrango las instrucciones dentro del loop ! ! son ejecutadas por un thread en particular ! !======================================================================== print *, "-------------- PARALELIZACION DE UN BUCLE --------------" !$OMP PARALLEL !$OMP DO do i = 1,n print *, "Paralelizacion del vector, indice: ",i," thread: ",omp_get_thread_num() vector(i) = i end do !$OMP END DO !$OMP END PARALLEL print *,"vector: ",vector print*, "----------------------------------------------------------------------------" print *, !============ proteccion de variables del thread ======================== ! Hay circunstancias que requieren que cierta variable que usa un thread ! ! no sea modificada por otro, estas variables deben de ser protegidas ! ! por el thread, hay una copia por cada thread de la variable ! !========================================================================= print *, "-------- PROTECCION DE VARIABLES ----------" !$OMP PARALLEL PRIVATE(temp) SHARED(vector,vector1,n) !$OMP DO do i=1,n temp = vector(i)*2 vector(i) = temp print *,"Modificacion del vector, indice: ",i," thread: ",omp_get_thread_num()," temp: ",temp end do !$OMP END DO !$OMP END PARALLEL print*,"vector: ",vector print*,"-----------------------------------------" print*, !================== operaciones de reduccion ================================================= ! puede ser necesario tener variables que dependan del flujo del loop ! ! la operacion de reduccion pemite reducir los valores de los distintos threads en uno unico ! !============================================================================================= print *, "------ VARIABLES DE REDUCCION -------" suma = 0 !$OMP PARALLEL !$OMP DO REDUCTION(+:suma) do i = 1,n suma = suma + vector(i) end do !$OMP END DO !$OMP END PARALLEL print*, "suma: ",suma print*, "-----------------------------------------------------" print *, !==================================================================================================! ! Como ejempo vamos a calcular la integral definida de reimann de cos(x) entre 0 y pi/2 ! ! !==================================================================================================! print *, "--- INTEGRAL DEFINIDA DE RIEMANN ----" nx = 1000 x0 = 0 x1 = 1.5707963 ! pi/2 delta_x = (x1-x0)/(nx-1) integral = 0 !$OMP PARALLEL !$OMP DO REDUCTION(+:integral) do j = 1,nx-1 integral = integral + cos(x)*delta_x x = x + delta_x end do !$OMP END DO !$OMP END PARALLEL print *, "integral de cos(x) entre 0 y pi/2: ",integral end program openmp