---
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;
}
```