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