---
# System prepended metadata

title: Open MP - Resumen

---

---
title: Open MP - Resumen
---

## Funciones y Constantes de ambiente
+ `int omp_get_num_threads()`
    + Regresa el número de hilos usados en una sección paralela
+ `int omp_get_thread_num()`
    + Regresa el hilo usado en una sección paralela
+ `void omp_set_num_threads()`
    + Permite ingresar el número de hilos que usar.
+ `OMP_NUM_THREADS`
    + Regresa el número máximo de hilo que puedes usar.

## Estructura general

```cpp
#include <omp.h>

int main () {
    
int var1, var2, var3;
// Código serial
    #pragma omp parallel private(var1, var2) shared(var3)
    {
    // Ejecución de código por los hilos
        #pragma omp section{
        
        }
        
        #pragma omp section{
    
        }
    // Todos los hilos se unen al maestro y se disuelven
    }
// Código serial
    
}
```

## Constructos de sincronización y candados

### Constructos para compartir trabajo
Se usan para distribuir la chamba un ciclo for entre los varios hilos.
+ La opción `static` hace que `chunk_size` asigne el número de iteraciones que cada hilo ejecute **desde el principio** del loop   
+ La opción `dynamic` hace que `chunk_size` asigne el número de iteraciones que cada hilo ejecute **cuando un hilo esté disponible**
```cpp
#pragma omp for schedule(dynamic, chunk_size){

}
#pragma omp for schedule(static, chunk_size){

}
```

### Master
El código aquí lo ejecutará el hilo **master** una sola vez.   
Las variables aquí persistirán después de la paralelización.

```cpp
#pragma omp master{
   //Código aquí
}
```

### Sections
Especifica las secciones que serán compartidas entre los hilos. **A cada hilo le tocará una sección**.

```cpp
#pragma omp section{
   //Código aquí
}
```

### Single
Este bloque de código será serial y ejecutado por un solo hilo.

```cpp
#pragma omp single{
    //Código aquí
}
```

### Barrier
Obliga a todos los hilos a **pararse** antes de continuar.

```cpp
#pragma omp paralell private(var1, var2) shared(var3)
{
    #pragma omp section{
       //Código aquí
    }
    
    #pragma omp section{
       //Código aquí
    }

    #pragma omp section{
       //Código aquí
    }
    
    #pragma omp barrier
    //Forzará a que se ejecuten PRIMERO los bloques de arriba ANTES de continuar.
}
```

### Atomic
Ejecuta **una sola instrucción** a nivel máquina.
```cpp
#pragma omp paralell shared(x)
{
    #pragma omp atomic
    x += 2;
    //Solo ejecutará la suma de arriba y ya
}
```

### Critical
Indica que su sección de código de debe ejecutar **todos los hilos, uno a la vez**, `single`, que es ejecutado **por el primer hilo disponible**.

Por ejemplo, en el siguiente código:
```cpp
int a=0, b=0;
#pragma omp parallel shared(a,b)
{
    omp_set_num_threads(4);
    #pragma omp single
    a++;
    #pragma omp critical
    b++;
}
printf("single: %d -- critical: %d\n", a, b);
```

Se imprimirá:
```
single: 1 -- critical: 4
```
### Reduction
Distribuye una operación en específico entre los hilos.
```cpp
#pragma omp for schedule(static, chunk_size) reduction(+:suma)
    suma += expression
#pragma omp for schedule(static, chunk_size) reduction(*:mult)
    mult *= expression
```

También se puede usar en loops.
```cpp
int i = 0;
int suma = 0;

pragma omp parallel for private(i) reduction(+:asum)
for (i = 0;i<100;i++){
   suma+=i; 
} 
```