100% encontró este documento útil (1 voto)
153 vistas36 páginas

Introducción a Arquitecturas GPU

Este documento presenta las arquitecturas de las GPU y comparte conceptos clave sobre sus diferencias con las CPU. Explica que las GPU están diseñadas para procesamiento masivamente paralelo de granos finos a través de shaders programables, mientras que las CPU están optimizadas para instrucciones secuenciales. También introduce modelos de programación como CUDA y OpenCL para aprovechar las GPU en aplicaciones de propósito general.

Cargado por

Nadia M
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
100% encontró este documento útil (1 voto)
153 vistas36 páginas

Introducción a Arquitecturas GPU

Este documento presenta las arquitecturas de las GPU y comparte conceptos clave sobre sus diferencias con las CPU. Explica que las GPU están diseñadas para procesamiento masivamente paralelo de granos finos a través de shaders programables, mientras que las CPU están optimizadas para instrucciones secuenciales. También introduce modelos de programación como CUDA y OpenCL para aprovechar las GPU en aplicaciones de propósito general.

Cargado por

Nadia M
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 36

Procesadores avanzados

Arquitecturas de GPU

Ing. Alejandro C. Rodríguez Costello


([email protected])

“Those who can imagine anything, can create the impossible.”


Alan Turing
Objetivo
 Entender que es una GPU (graphic processing unit).
 Comparar las arquitecturas de CPU con GPU.
 Entender la importancia de la programación masiva
paralela y las motivaciones para GPGPU (General
Programing on GPU).
 Presentar un caso de uso básico: Nvidia Gforce
 Aprender conceptos básicos para programar GPUs con
CUDA y OpenCL.

Arquitectura de las Computadoras II Arquitecturas de GPU 2


Pipeline gráfico conceptual

Arquitectura de las Computadoras II Arquitecturas de GPU 3


Etapas de un pipeline gráfico

Arquitectura de las Computadoras II Arquitecturas de GPU 4


Motivación para usar GPU vs CPU
 No se puede serguir aumentando el clock: debido a
límites físicos de los materiales actuales.
 Límites de integración: no se pueden hacer transistores
más pequeños por problemas de fabricación.
 Restricciones de energía y calor: límites tecnológicos
(CMOS) y elevado consumo.
 Límites al paralelismo ILP: pipelines más largos
terminan con menor rendimiento.
 Límite a manycore: no se pueden integrar demasiados
cores en una sola pastilla (128 cores AMD Epic, 2019).

Arquitectura de las Computadoras II Arquitecturas de GPU 5


Rendimiento GPU vs CPU

Arquitectura de las Computadoras II Arquitecturas de GPU 6


Aspectos importantes de la GPU
 Poseen un pipeline gráfico.
 Utilizan unidades aritméticas programables (shaders).
 Fueron pensadas desde el inicio SIMD.
 Soportan muchos flujos de ejecución (threads) por eso
tambien se las llama SIMT (single instruction multiple
threads)
 Pueden generalizar los shaders (unified architecture).
 Tienen una jerarquía de memoria compleja.
 Aprovechan al máximo el principio de localidad.
 Gran velocidad de acceso a memoria (DDR5).

Arquitectura de las Computadoras II Arquitecturas de GPU 7


Arquitectura CPU vs GPU

Arquitectura de las Computadoras II Arquitecturas de GPU 8


Comunicación GPU-CPU

Arquitectura de las Computadoras II Arquitecturas de GPU 9


Limitaciones de la GPU
 No puede acceder directamente a la memoria del
procesador.
 Se requiere hacer copia explícita de los datos entre
CPU y GPU (memcpy).
 No se puede hacer uso en el código de la salida
estandar (printf).
 Depuración compleja y ardua.

Arquitectura de las Computadoras II Arquitecturas de GPU 10


Familia de GPUs Nvidia
 Gforce: orientada al consumo masivo multimedia
(videojuegos, edición de video, fotografía digital, etc.).
 Quadro: orientada a soluciones profesionales en
workstations 3D (ingeniería, arquitectura, animación).
 Tesla: orientada al computación de alta prestaciones
(HPC)

Arquitectura de las Computadoras II Arquitecturas de GPU 11


Aplicaciones de la GPU
 GPGPU: usar la GPU para aplicaciones de propósito
general.
 Las aplicaciones que mejor se adaptan:
 Trabajan sobre grandes vectores de datos
 Tienen paralelismo de grano fino SIMD
 Dominios adecuados de aplicación:
 Álgebra lineal (producto escalar y suma de matrices)
 Procesamiento de señales (digital image processing)
 Mecánica computacional (computational fluidic
dynamics).
 Inteligencia artificial

Arquitectura de las Computadoras II Arquitecturas de GPU 12


Desafios para programar GPU
 La programación CPU y GPU no son compatibles.
 Todo dato a procesar debe convertirse en texturas para
aprovechar el procesamiento por shaders.
 Se usa la técnica render-to-texture para escribir ya que
no se puede acceder trivialmente a la memoria.
 El cálculo se realiza mediante flujos de procesador de
fragmentos (pixel shader threads).
 Se hacen necesarios estandars como CUDA u OpenCL.

Arquitectura de las Computadoras II Arquitecturas de GPU 13


Caso Nvidia G80
 2006 aparece la arquitectura G80 (Tesla).
 Utiliza shaders unificados: no diferencia entre vectors o
pixel shaders a nivel procesadores (SP).
 Se orienta a flujos masivos (massive threads).
 Utiliza IEEE 754 (floats).
 Pipeline gráfico con soporta DirectX 10 y OpenGL 3.3
 Utiliza dos etapas: carga y control de flujos.
 Los flujos se diferencian por su clasificación.
 El procesamiento se realiza en bloques de 16 SPs
 Comparten cache y texturas.
https://en.wikipedia.org/wiki/GeForce_8_series

Arquitectura de las Computadoras II Arquitecturas de GPU 14


Uso de shaders unificados

Arquitectura de las Computadoras II Arquitecturas de GPU 15


Stream processors SP

Arquitectura de las Computadoras II Arquitecturas de GPU 16


Nvidia G80 Unified arquitecture

Arquitectura de las Computadoras II Arquitecturas de GPU 17


Otras alternativas AMD R600

Arquitectura de las Computadoras II Arquitecturas de GPU 18


Otras alternativas Intel Larrabee (x86)

La cantidad de núcleos y la cantidad y tipo de coprocesadores y bloques de E/S son dependientes de la implementación.

Arquitectura de las Computadoras II Arquitecturas de GPU 19


Modelos de programación GPGPU
 OpenGL: es un modelo open source para programación
gráfica.
 Direct3D: es otro modelo de programación gráfica.
 CUDA: Compute Unified Device Architecture, es un
modelo propietario para programación general de las
GPUs de Nvidia.
 OpenCL: es un modelo open source multiplataforma
para programación paralela, subconjunto de C99.

Arquitectura de las Computadoras II Arquitecturas de GPU 20


Arquitectura conceptual CUDA

Arquitectura de las Computadoras II Arquitecturas de GPU 21


Entorno de programación CUDA

nvcc

Arquitectura de las Computadoras II Arquitecturas de GPU 22


Terminología CUDA
 Kernels: funciones especiales en ANSI C. Usan palabras
claves para poder tratar con el paralelismo.
 Threads: o flujos, son la unidad de ejecución básica de
un kernel.
 Grids: grupos de ejecución de threads pertenecientes a
un kernel.
 Block: subconjunto de ejecución de threads dentro de un
grid.

Arquitectura de las Computadoras II Arquitecturas de GPU 23


Ejemplo de ejecución de un programa CUDA

Arquitectura de las Computadoras II Arquitecturas de GPU 24


Ejemplo de ejecución de un kernel

Arquitectura de las Computadoras II Arquitecturas de GPU 25


Modelo de memoria CUDA

Arquitectura de las Computadoras II Arquitecturas de GPU 26


Ejemplo CPU vs kernel de CUDA
void matrix_add_cpu (fload *A, float *B, float *C, int N)
{
int i, j, index;
for (i=0; i<N; i++){
for (j=0; j<N; j++){
index = i+j*N;
C[index] = C[index] + B[index];
}
}
}

int main(){matrix_add_gpu (fload *A, float *B, float *C, int N)


__global__
{ matrix_add_cpu(a, b, c, N);
} int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
int index = i + j*N;
if (i<N && j<N){
C[index] = A[index] + B[index];
}
}
int main(){
dim3 dimBlock(blocksize, blocksize);
dim3 dimGrid(N/dimBlock.x, N/dimBlock.y);
matrix_add_gpu<<<dimGrid, dimBlock>>>(a, b, c, N);
}
Arquitectura de las Computadoras II Arquitecturas de GPU 27
Identificación de un thread dentro de un kernel

Arquitectura de las Computadoras II Arquitecturas de GPU 28


Organización de los threads dentro de un grid

Arquitectura de las Computadoras II Arquitecturas de GPU 29


Similitudes entre OpenCL y CUDA
OpenCL CUDA

Kernel Kernel

Programa procesador principal Programa procesador principal

NDRange (rango de dimensión N) Grid

Tarea elemental (work item) Flujo

Grupo de tareas (work group) Bloque

get_global_id(0); blockIdx.x * blockDim.x +threadIdx.x

get_local_id(0); threadIdx.x

get_global_size(0); gridDim.x*blockDim.x

get_local_size(0); blockDim.x

Arquitectura de las Computadoras II Arquitecturas de GPU 30


Relación entre tareas y grupos

Arquitectura de las Computadoras II Arquitecturas de GPU 31


Arquitectura conceptual OpenCL

Arquitectura de las Computadoras II Arquitecturas de GPU 32


Modelo de memoria OpenCL

Arquitectura de las Computadoras II Arquitecturas de GPU 33


Ejemplo de un kernel OpenCL

__kernel void matrix_add_opencl ( __global const float *A,


__global const float *B,
__global float *C,
int N) {
int i = get_global_id(0);
int j = get_global_id(1);
int index = i + j*N;
if (i<N && j<N){
C[index] = A[index] + B[index];
}
}

Arquitectura de las Computadoras II Arquitecturas de GPU 34


Gestión de dispositivos mediante contextos

Arquitectura de las Computadoras II Arquitecturas de GPU 35


Ejemplo de uso de contextos en OpenCL
main(){
// Inicialización de variables, etc.
(...)

// 1. Creación del contexto y cola en el dispositivo


cl_context context = clCreateContextFromType(0, CL_DEVICE_TYPE_GPU, NULL, NULL, NULL);
// Para obtener la lista de dispositivos GPU asociados al contexto
size_t cb;
clGetContextInfo( context, CL_CONTEXT_DEVICES, 0, NULL, &cb);
cl_device_id *devices = malugar(cb);
clGetContextInfo( context, CL_CONTEXT_DEVICES, cb, devices, NULL);
cl_cmd_queue cmd_queue = clCreateCommandQueue(context, devices[0], 0 , NULL);
// 2. Definición de los objetos en memoria (matrices A, B y C)
cl_mem memobjs[3];
memobjs[0] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
sizeof(cl_float)*n, srcA, NULL);
memobjs[1] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
sizeof(cl_float)*n, srcB, NULL);
memobjs[2] = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_float)*n, NULL, NULL);

// 3. Definición del kernel y argumentos


cl_program program = clCreateProgramWithSource(context, 1, &program_source, NULL, NULL);
cl_int err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
cl_kernel kernel = clCreateKernel(program, "matrix_add_opencl", NULL);
err = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobjs[0]);
err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobjs[1]);
err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&memobjs[2]);
err |= clSetKernelArg(kernel, 3, sizeof(int), (void *)&N);

// 4. Invocación del kernel


size_t global_work_size[1] = n;
err = clEnqueueNDRangeKernel(cmd_queue, kernel, 1, NULL, global_work_size,
NULL, 0, NULL, NULL);

// 5. Lectura de los resultados (matriz C)


err = clEnqueueReadBuffer(context, memobjs[2], CL_TRUE, 0, n*sizeof(cl_float),
dstC, 0, NULL, NULL);
(...)

Arquitectura de las Computadoras II Arquitecturas de GPU 36

También podría gustarte