Cláusula Schedule
Anterior | Siguiente |
Es posible controlar la estrategia de distribución y el tamaño del bloque (número de iteraciones consecutivas) asignado a cada hilo. Esto se hace con la cláusula schedule.
Sintaxis básica
#pragma omp parallel for schedule(static|dynamic,<chunk_size>)
for(...){
<loop body>
}// implicit barrier here
Las estrategias fundamentales son:
static
- La distribución se hace en tiempo de compilación a manera round-robin, es decir, asignando cada bloque consecutivo de iteraciones a un hilo diferente.
- Si no se especifica un tamaño de bloque, cada hilo recibirá un bloque de tamaño similar (chunk_size=num_iterations/num_threads).
dynamic
- La distribución se hace en tiempo de ejecución, asignando cada bloque consecutivo de iteraciones al hilo con menos carga, de tal manera que se balancee la ejecución.
- Si no se especifica un tamaño de bloque, cada hilo recibirá una iteración (chunk_size=1).
Ejemplo 1
Vamos a distribuir las iteraciones entre los hilos de dos en dos:
#include <stdio.h>
#include <omp.h>
int main(){
int m = omp_get_thread_num();
printf("master thread=%d in serial region\n", m);
#pragma omp parallel for schedule(static,2)
for(int i=0; i<16 ; i++){
int f = omp_get_thread_num();
printf("i=%d processed by thread=%d\n", i, f);
} // implicit barrier here
printf("master thread=%d in serial region\n", m);
}
¿Cómo compilar?
clang -fopenmp -I/home/user/llvm/llvm-build/projects/openmp/runtime/src/
-o schedule-000 schedule-000.c
¿Cómo ejecutar?
./schedule-000
Salida
master thread=0 in serial region
i=0 processed by thread=0
i=1 processed by thread=0
i=8 processed by thread=0
i=9 processed by thread=0
i=2 processed by thread=1
i=3 processed by thread=1
i=10 processed by thread=1
i=11 processed by thread=1
i=6 processed by thread=3
i=7 processed by thread=3
i=14 processed by thread=3
i=15 processed by thread=3
i=4 processed by thread=2
i=5 processed by thread=2
i=12 processed by thread=2
i=13 processed by thread=2
master thread=0 in serial region
Se crean bloques de 2 iteraciones y se van rotando los hilos que reciben cada bloque.
Ejemplo 2
Vamos a distribuir las iteraciones entre los hilos de dos en dos:
#include <stdio.h>
#include <omp.h>
int main(){
int m = omp_get_thread_num();
printf("master thread=%d in serial region\n", m);
#pragma omp parallel for schedule(dynamic,2)
for(int i=0; i<16 ; i++){
int f = omp_get_thread_num();
printf("i=%d processed by thread=%d\n", i, f);
} // implicit barrier here
printf("master thread=%d in serial region\n", m);
¿Cómo compilar?
clang -fopenmp -I/home/user/llvm/llvm-build/projects/openmp/runtime/src/
-o schedule-001 schedule-001.c
¿Cómo ejecutar?
./schedule-001
Salida
master thread=0 in serial region
i=8 processed by thread=2
i=9 processed by thread=2
i=10 processed by thread=2
i=11 processed by thread=2
i=12 processed by thread=2
i=13 processed by thread=2
i=14 processed by thread=2
i=15 processed by thread=2
i=6 processed by thread=2
i=7 processed by thread=2
i=2 processed by thread=3
i=3 processed by thread=3
i=0 processed by thread=0
i=1 processed by thread=0
i=4 processed by thread=1
i=5 processed by thread=1
master thread=0 in serial region
Se crean bloques de 2 iteraciones y se van asignando a los hilos que tengan menos trabajo. Observamos que el hilo 2 se ha encargado de 5 bloques, mientras que los demás hilos solo recibieron 1 cada uno.
Preguntas
- Experimenta con diferentes versiones del tamaño del chunk y diferentes estrategias de scheduling.
- Intenta escribir dentro del bucle un problema de tipo irregular.
Anterior | Siguiente |
Estás en el Nivel 2: Bucles paralelos y tareas concurrentes con OpenMP. ¿Deseas volver al inicio?