DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad...

35
PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 1/30 PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual DESARROLLO DE APLICACIONES EN CUDA Curso 2014 / 15 Procesadores Gráficos y Aplicaciones en Tiempo Real Alberto Sánchez © GMRV 2005-2015

Transcript of DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad...

Page 1: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual1/30

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual

DESARROLLO DE APLICACIONES

EN CUDACurso 2014 / 15

Procesadores Gráficos y Aplicaciones en Tiempo RealAlberto Sánchez

© GMRV 2005-2015

Page 2: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual2/30

Contenidos

• Introducción• Debugging• Profiling• Streams• Diseño de

aplicaciones CUDA

Page 3: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual3/30

CPU vs GPU

CPUOrientado a Latencia

GPUOrientado a Throughput

Page 4: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual4/30

CPU vs GPU

• CPUs pueden ser 10+X más rápidas que GPUs para código secuencial– Caches grandes– Control sofisticado. Predicción de saltos, pipeline– ALU poderosa

• GPUs pueden 10+X más rápidas que CPUspara código paralelo– Caches pequeñas– Control sencillo– Múltiples ALUs eficientes energéticamente

Page 5: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual5/30

Anatomía de una aplicación CUDA

• Código serie se ejecuta en un thread en CPU• Código paralelo se ejecuta en treads GPUs

Page 6: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual6/30

Aplicación CUDA

Page 7: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual7/30

Aplicación CUDA

• Kernel: función llamada desde CPU que ejecuta en GPU como un array de threads en paralelo– Solo puede acceder a memoria en GPU– Todos los threads ejecutan el mismo código, aunque

pueden tomar diferentes caminos– Cada thread tiene un identificador (threadIdx.x, blockIdx.x,

…) • Permite seleccionar datos de entrada• Decisiones de control

• Funciones se deben declarar:– __global__ : funcion kernel en GPU lanzada desde CPU.

Debe devolver void– __device__ : funciones en GPU– __host__ : (por defecto) funciones en GPU

Page 8: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual8/30

Aplicación CUDA• Threads esta agrupados en bloques (blockIdx.x, …)

– La dimensión del bloque se puede conocer con blockDim• Los bloques están agrupados en un grid y pueden ejecutar en

cualquier orden, concurrentemente o secuencialmente• Un kernel es ejecutado como un grid de bloques de threads

Page 9: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual9/30

Jerarquia de memoria

• memoria compartida:– __shared__ int a[SIZE];– Accesible por cada thread del bloque– Elevado ancho de banda

• Memoria global– Visible desde reserva hasta liberación de memoria en código

• cudaMalloc(void ** pointer, size_tnbytes)• cudaMemset(void * pointer, int value, size_tcount)• cudaFree(void* pointer)

– Accesible por todos los threads– Menor ancho de banda

Page 10: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual10/30

Aplicación CUDA

Page 11: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual11/30

Condiciones de carrera

• Varios threads en ejecución• Comparten datos• El acceso concurrente a esos datos puede

llevar a resultados erróneos:• Ejemplo:

– Suma de 1 millón de threads, divididos en bloques. Cada uno de ellos suma en una posición del array correspondiente a su bloque b “cuentaGM[b]”

Page 12: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual12/30

Condiciones de carrera

• cuentaMG[b]++ para thread0:register1 = cuentaMG[b]register1 = register1 + 1cuentaMG[b] = register1

• Supongamos que cuentaMG[b] vale 5. Puede suceder que ambos threads lleguen a la instrucción que modifica cuentaMG[b] y se ejecute lo siguiente:

T0: register1 = cuentaMG[b] {register1 = 5}

T0: register1 = register1 + 1 {register1 = 6}

T1: register2 = cuentaMG[b] {register2 = 5}

T1: register2 = register2 + 1 {register2 = 6}

T0: cuentaMG[b] = register1 {cuenta = 6 }

T1: cuentaMG[b] = register2 {cuenta = 6}

• Se ha llegado al valor de cuentaMG[b] = 6 en memoria global (MG) que es incorrecto.

• cuentaMG[b]++ para thread1:register2 = cuentaMG[b]

register2 = register2 + 1

cuentaMG [b] = register2

Page 13: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual13/30

Condiciones de carrera

• Esto sucede por permitir que ambos threadsmanipulen variables compartidas al mismo tiempo

• Cuando varios threads acceden a los mismos datos de forma concurrente y el resultado de la ejecución depende del orden concreto en que se realicen los accesos, se dice que hay una condición de carrera .

• Necesitamos mecanismos para tratar estas situaciones.– Ej: atomicAdd

Page 14: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual14/30

Debugging

• Se requiere la instalación de CUDA Toolkit– Actualmente v7.0

• Se han extendido las herramientas de depuración tradicionales:– cuda-gdb. Necesario compilar con el flag –G

nvcc –g –G code.cu –o executable

– ddd. Más visual– cuda-memcheck– Nsight:

• Visual Studio (Windows) • Eclipse (Linux/Mac)

Page 15: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual15/30

Debugging• Devices cuya versión es superior a 2.0 permiten

depurar dentro de la tarjeta. Sencillez:– Utilizando librería estandar printf

#include " stdio.h"

__global__ kernel(){….printf("[%d][%d][%d] = %f\n",r,c,k,output);....}

– Depuración con Nsight dentro del propio kernel. Se pueden establecer breakpoints condicionales (ej. indicando el id del thread (threadIdx.x == id))

Page 16: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual16/30

Debugging

• Devices 1.0 y 1.1 no permiten depuración dentro de la tarjeta. Se puede hacer de forma más compleja:– Librería cuprintf: imprime a través de la memoria de texturas

#include "cuPrintf.cuh"#include "cuPrintf.cu"…cudaPrintfInit();kernel<<<nBlocks,nThreads>>>();cudaPrintfDisplay(stderr, true);cudaPrintfEnd();…

__global__ kernel(){….cuPrintf("[%d][%d][%d] = %f\n",r,c,k,output);....}

Page 17: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual17/30

Compilación• Para simplificar el proceso de compilación lo habitual es hacer un

fichero Makefile en el mismo directorio donde estén los fuentes • Posible definición de variables:

CFLAGS=-I<path1> -I<path2> ...CC=nvcc

• Ordenados en forma de reglas:objetivo: dependencias

comandos

• Reglas virtuales: sin dependenciasclean :

rm *.o *~

• Reglas implicitas: programa : programa.oprograma.o : programa.c

• Reglas patrón: %.o : %.c

$(CC) $(CFLAGS) $< -o $@

$< primera dependencia de la regla$@ primer objetivo de la regla

• Posibilidad de utilizar cmake– Permite crear ficheros Makefile, – Permite adaptación a IDE de programación: Visual Studio, Eclipse, Xcode, …

Page 18: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual18/30

Profiling

• Factores que limitan el rendimiento:– Ancho de banda de memoria– Ancho de banda de instrucciones– Latencia

• Herramientas de Profiling– Nvidia Visual Profiler:

• Herramienta propia: nvvp• Integrado en Nsight

– nvprof: línea de comandos

Page 19: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual19/30

Profiling

• Las herramientas de profiling en CUDA no requieren cambios en las aplicaciones

• Pero algunas modificaciones simples mejoran la utilidad y eficacia

• Anotaciones:– Reducen el volumen de los datos a analizar– Mejoran la usabilidad– Mejoran la precisión del análisis

Page 20: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual20/30

Profiling

• Limitar profiling a una región de interés:– cuda_profiler_api.h

• cudaProfilerStart() • cudaProfilerStop()

– nvprof --profile-from-start off para deshabilitar profiling al comienzo de la aplicación

– Desabilitar ‘Start execution with profilingenabled’ en nvpp o Nsight

Page 21: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual21/30

Profiling

• Que nos permite profiling– Permite ver cuando cada thread de la CPU

invoca funciones de CUDA (TimeView)– Comprender las interacciones de la CPU / GPU

• Comprobar si se está aprovechando tanto CPU cómo GPU

• Saber si está la CPU esperando por la GPU o viceversa

– Buscar oportunidades de concurrencia• Solapar transferencias (memcpy()) y kernels• Solapar kernels concurrentes. Ojo con las condiciones

de carrera

Page 22: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual22/30

Streams• Algunos dispositivos CUDA permiten solapar la ejecución de kernels

con las copias entre host y device mediante el uso de streams

int dev_count;cudaDeviceProp prop;

cudaGetDeviceCount (&dev_count);for (int i= 0; i<dev_count; i++) {

cudaGetDeviceProperties(&prop,i);

if (prop.deviceOverlap) …

• Cada stream es una cola FIFO de tareas (kernels y copias (memcpy). • El driver asegura que las tareas de una cola se procesan de forma

ordenada• Las tareas que ejecutan en diferentes streams pueden ejecutar en

paralelo permitiendo Task Paralellism• Los eventos en CUDA permiten a la CPU sincronizar los diferentes

streams

Page 23: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual23/30

Streams

• Para poder solapar las transferencias de datos es necesario realizarlas de forma asíncrona

cudaStream_t stream0;cudaStream_t stream1;

cudaMemcpyAsync(h, d, size, …, stream0 );cudaMemcpyAsync(h, d, size, …, stream1 );kernel0<<<size/numThreads, numThreads, 0, stream0 >>>(d,...);kernel1<<<size/numThreads, numThreads, 0, stream1> >>(d,...);cudaMemcpyAsync(h, d, size, …, stream0 );cudaMemcpyAsync(h, d, size, …, stream1 );

Page 24: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual24/30

Streams• Para sincronizar streams se utiliza

cudaStreamSynchronize (stream_id);

• Espera hasta que todas las tareas del stream han finalizado• Para esperar por todos los streams se hace mediante:

cudaDeviceSynchronize();

• Además de los streams se pueden tener diferentes GPUs en funcionamiento. La CPU siempre tiene en contexto una GPU. Para cambiar de contexto se utiliza

cudaSetDevice(i)cudaMalloc(&d[i], size); //Para provocar un cambio de contexto

• Se pueden gestionar cada una de las GPUs en paralelo mediante el uso de streams

• La memoria unificada (UVA) existente en CUDA en las últimas versiones del toolkit posibilita un único espacio de direcciones de memoria para GPUs y CPU que se puede utilizar para copias directas entre los diferentes dispositivos

Page 25: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual25/30

Streams• La versión 6 de CUDA toolkit elimina la necesidad de hacer copias

CPU-GPU

Page 26: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual26/30

Cuda 6 en adelante

Page 27: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual27/30

Cuda 6 en adelante

• Elimina la necesidad de realizar múltiples copias

Page 28: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual28/30

Cuda 6 en adelante

• Elimina la necesidad de realizar múltiples copias

Page 29: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual29/30

Diseño de aplicaciones CUDA

Tres reglas básicas basadas en la arquitectura:

1. Poner los datos en la GPU y mantenerlos allí2. Dar a la GPU suficiente trabajo que hacer3. Centrarse en la reutilización de datos en la

GPU: evita limitaciones de ancho de banda de memoria

Page 30: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual30/30

Diseño de aplicaciones CUDA

• Las transferencias de datos entre CPU-GPU son muy costosas– Reducir en la medida de lo posible– Cuando cudaMemcpy() copia un array, se

implementa como una transferencia de DMA– La dirección se traduce y se comprueba que la

página existe en memoria al principio de cada transferencia de DMA sin volver a traducir

– El sistema operativo podría accidentalmente paginar otra página de memoria virtual en la misma ubicación física

Page 31: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual31/30

Diseño de aplicaciones CUDA– Pinned memory son páginas de memoria

marcadas para que no puedan expulsarse de memoria principal

• cudaHostAlloc(): indicando cudaHostAllocDefault• cudaFreeHost()

– Si el origen o destino de cudaMemcpy() no está en pinned memory, hay que copiarlo

– cudaMemcpy() es aproximadamente 2 veces más rápido con pinned memory

– Pinned memory es un recurso limitado. Si se sobreexplota puede llevar a hiperpáginación

Page 32: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual32/30

Diseño de aplicaciones CUDA

• Conveniencia de colocar los datos alineados en memoria para que los accesos sean coalescentes– Primer factor para conseguir eficiencia– Capacidad de la arquitectura para obtener 16 palabras de

memoria simultáneamente (en un único acceso). Una para cada thread del half-warp (16)

• Tamaños de bloque múltiplo de 16 facilitan el acceso a memoria• En cualquier caso, para no desperdiciar recursos, el tamaño de

bloque debería ser múltiplo del tamaño de warp (32)

– Aprovecha la localidad espacial en memoria– Se consigue bajo ciertos patrones de acceso

Page 33: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual33/30

Diseño de aplicaciones CUDA• Aprovechar al máximo los recursos de la GPU

– Tratar de minimizar la divergencia de warps– Thread Level Parallelism:

• Lanzar suficientes threads para maximizar throughtput• Ocupancia: número de warps ejecutando concurrentemente por

ciclo en un multiprocesador dividido por el máximo número de warps que pueden estar en un SM

• Una elevada ocupancia implica que el planificador en cada SM tiene bastantes warps para elegir ocultando latencias de ALU y memoria.

• Conviene especificar múltiples bloques por SM (múltiplo del ńumero de SM) para ejecutar concurrentemente dentro del mismo

• Si es posible, especificar un gran número de bloques por grid

Page 34: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual34/30

Diseño de aplicaciones CUDA

– Instruction Level Parallelism:• Alta ocupancia no tiene porque traducirse en elevado rendimiento• Usar menos threads posibilita tener mas registros por thread y más

memoria compartida para cada uno de ellos• Se puede intentar procesar varios elementos por thread• Si las operaciones son independientes se pueden ocultar latencias

de ALU, por lo que se pueden beneficiar problemas aritméticamente intensivos

• Más difícil para ocultar latencias de memoria

Page 35: DESARROLLO DE APLICACIONES EN CUDAPGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual 32/30 Diseño de aplicaciones CUDA • Conveniencia de colocar los datos alineados

PGATR -- Máster en Informática Gráfica, Juegos y Realidad Virtual35/30

Diseño de aplicaciones CUDA

• Acceso a memoria global muy costoso– La memoria compartida (16KB-48KB por MP) es

muchísimo más rápida• Cada bloque de threads copia su parte de datos de

trabajo (tile) a memoria compartida (__shared__)• El tamaño de los datos puede ser dinámico:

extern __shared__ int data[];…kernel<<<nBlocks,nThreads,tileSize>>>;

• Se comparte la información del tile entre los threads del bloque y se trabaja sobre memoria compartida

• El resultado final se copia a global para su actualización• Necesario rediseñar algoritmos