CHAPTER FIVE DISCUSSION
5.2 Potential prognostic factors
En sus inicios las GPU´s fueron diseñadas como procesadores gráficos, soportando únicamente funciones fijas. A finales de los años 90´s este hardware se hizo más sencillo de programar, y dio como resultado a la primera GPU de NVIDIA en 1999 (Historia de Nvidia: de la tarjeta gráfica al procesador móvil., 2014), a partir de ese momento artistas, desarrolladores de videojuegos así como científicos comenzaron a utilizar las GPU´s para acelerar sus aplicaciones aprovechando el enorme rendimiento en operaciones de punto flotante, y es aquí donde dio inicio el GPU de propósito general (General Purpose GPU - GPGPU) (Plataforma de Computacion Paralela CUDA.).
Pero el GPU de propósito general no era sencillo, inclusive para las personas que conocían el manejo de librerías graficas como OpenGL y CG, se encontraban con dificultades para programar las GPU´s y representar sus problemas con triángulos y polígonos, esta complejidad limitaba el acceso a la enorme capacidad de las GPU en el campo científico.
En el año 2003 un equipo de investigadores junto con Ian Buck dieron a conocer Brook (BrookGPU: Introduction, 2014), fue el primer modelo de programación ampliamente adoptado que extendía el lenguaje C con construcciones de datos en paralelo. Utilizando conceptos como streams, núcleos, operadores de reducción, el compilador Brook y el tiempo de ejecución del sistema permitieron utilizar a la GPU como un procesador de propósito general bajo un lenguaje de alto nivel. Lo más importante era que los programas de Brook no solo eran más sencillos de escribir que el código estándar de GPU, sino que eran mucho más rápidos que códigos similares ya existentes.
NVIDIA sabía que un hardware con tanta potencia tenía que hacerse acompañar de un software intuitivo de desarrollo, con este motivo invitó a Ian Buck para unirse a la empresa y trabajar en una solución para ejecutar sin problemas lenguaje C en la GPU, de esta manera se pudo unir el hardware con el software y en el año 2006 NVIDIA presentó
90
CUDA (Historia de Nvidia: de la tarjeta gráfica al procesador móvil., 2014), una solución para el desarrollo del GPU de propósito general.
6.3 CUDA.
CUDA es una interfaz de programación de aplicaciones (Application Programming Interface - API) creada por la Compañía NVIDIA para el cálculo de datos en paralelo que aprovecha el poder de las GPU´s para incrementar el rendimiento de los equipos de cómputo (Plataforma de Computacion Paralela CUDA.), algunas características de CUDA son su facilidad de uso ya que no es necesario tener conocimientos sobre las API´s gráficas, también es compatible con cualquier sistema operativo en donde se tenga instalada una GPU NVIDIA, es compatible con los compiladores de lenguaje C más populares como son el de la compañía Microsoft con Visual Studio y gcc.
La medición del rendimiento de los equipos de cómputo se hace por medio de las operaciones de coma flotante por segundo (Floating Point Operations Per Second - FLOPS) que son capaces de realizar.
91
En la Figura 6.1 se muestran los modelos de CPU´s y GPU´s aparecidos entre los años 2000 y 2014 junto al número de FLOPS que pueden alcanzar, se pueden apreciar 2 cosas una es el notable incremento de FLOPS que han tenido las GPU´s y también la gran diferencia de FLOPS alcanzadas entre GPU´s y CPU´s tanto en operaciones de precisión sencilla (Single Precision - SP) y doble (Double Precision - DP).
La tecnología CUDA es utilizada por desarrolladores, científicos e investigadores y tiene aplicaciones prácticas en diversos campos como el procesamiento de video e imágenes, biología y química computacional, simulación de la dinámica de fluidos, reconstrucción de imágenes de tomografías computarizadas, análisis sísmicos o el trazado de rayos, análisis de grandes cantidades de información, algoritmos de búsqueda exhaustiva, entre muchas otras.
Es necesario un kit de desarrollo de software para trabajar en la plataforma de cálculo paralelo CUDA este kit se integra a entornos de desarrollo de lenguajes C y C++ e incluye un compilador, bibliotecas matemáticas, guías de programación, manuales para el usuario, herramientas para corregir y optimizar el rendimiento de aplicaciones, todo lo necesario para implementar el paralelismo en el procesamiento de instrucciones y datos a distintos niveles. Todo esto permite que los desarrolladores puedan implementar sus aplicaciones bajo la arquitectura CUDA utilizando diferentes lenguajes de programación como C, C++ y Fortran los cuales son soportados de manera oficial por NVIDIA y otros de manera no oficial como Python, CIL, Java y Matlab mediante software de terceros.
6.3.1 Requisitos de CUDA.
Para poder ejecutar aplicaciones CUDA en un sistema de cómputo se necesita contar con los siguientes requisitos de Hardware y Software.
92
Sistemas Operativos Windows:
GPU con soporte para CUDA.
Sistema Operativo Windows XP, Vista, 7, 8, Server 2003, Server 2008. Herramientas de Desarrollo CUDA.
Compilador de lenguaje C incluido en Microsoft Visual Studio 2008, 2010 o 2012.
Sistemas Operativos Mac:
GPU con soporte para CUDA.
Sistema Operativo Mac OS X versión 10.7.5 o superior.
Compiladores gcc o Clang. Y tener instalada la herramienta toolchain utilizando Xcode.
Herramientas de Desarrollo CUDA.
Sistemas Operativos Linux:
GPU con soporte para CUDA.
Sistema Operativo Linux con soporte para CUDA. Compilador gcc y herramienta toolchain.
Herramientas de Desarrollo CUDA.
6.3.2 Instalación y Configuración de CUDA en Sistemas Operativos Windows.
La instalación de las herramientas de desarrollo CUDA y su configuración en un equipo de cómputo con sistema operativo Windows, consiste en los siguientes pasos:
Paso 1: Verificar que el sistema posea una GPU que soporte CUDA
93
Paso 2: Instalar un compilador de lenguaje C, C++ o una interfaz de desarrollo integrado como Visual Studio 2010 o Eclipse.
Paso 3: Actualizar los controladores de la tarjeta gráfica NVIDIA
http://www.nvidia.com/Download/index.aspx?lang=en-us.
Paso 4: Instalar las herramientas de desarrollo de CUDA
https://developer.nvidia.com/cuda-downloads que permiten la compilación de los
programas en CUDA y además contienen ejemplos para comenzar a programar.
Paso 5: Realizar una prueba de la instalación compilando y ejecutando alguno de los ejemplos de CUDA.
6.3.3 Organización en CUDA.
Para entender la programación bajo la arquitectura CUDA es necesario ver algunos conceptos como la capacidad computacional, hilos, bloques, mallas y núcleos.
La capacidad computacional (Compute Capability): es la que describe las características soportadas por el hardware CUDA. Las primeras series de GPU capaces de ejecutar instrucciones CUDA fueron los modelos GeForce 8800 GTX las cuales tenían una capacidad computacional de 1.0 algunas GPU más recientes tiene una capacidad computacional de 5.0.
Algunas de las características descritas a continuación están basadas en un hardware CUDA con capacidad computacional de 3.0.
Hilo (Thread): Es la unidad de trabajo básica de un núcleo y son asignados a núcleos de procesamiento de la GPU, cada hilo ejecuta el mismo código y opera sobre distintos valores. Es importante además conocer el término y la estructura de un “warp”, son las
94
unidades utilizadas en los sistemas de procesamiento en paralelo formados por grupos de 32 hilos y son útiles para efectos de rendimiento.
Bloque (Block): Es un arreglo de hilos los cuales trabajan de manera sincronizada y puede compartir información entre ellos mediante la memoria compartida. Los bloques se pueden formar de 1 a 3 dimensiones, manejar un máximo de 1024 hilos con un tamaño de x = 1024, y = 1024 y z = 64 por dimensión.
Malla (Grid): Es un arreglo bidimensional de bloques de hilos independientes, es el lugar de ejecución de un núcleo. Las mallas se manejan en 1 y 2 dimensiones con tamaños de x = 2147483647, y = 65535 y z = 65535 por dimensión.
Núcleo (Kernel): estas funciones especifican la parte de código que será ejecutada en la GPU de manera simultánea, al declarar un núcleo se debe especificar la malla esto es, el número de bloques e hilos que ejecutaran las mismas instrucciones sobre valores diferentes. Los núcleos están escritos en variantes de lenguaje C/C++.
6.3.4 Programa en CUDA.
Los pasos básicos de un programa en lenguaje C con funciones o núcleos en CUDA son los siguientes:
1. Almacenar la información del programa en la memoria principal del equipo de cómputo.
2. Copiar la información de la memoria principal del equipo de cómputo hacia la memoria de la GPU.
3. Realizar el procesamiento de la información en paralelo dentro de la GPU. 4. Copiar la información de la memoria de la GPU hacia la memoria principal del
equipo de cómputo.
95
Para entender el modelo de programación en CUDA, a continuación se muestra un código a manera de ejemplo, este código contiene las instrucciones para realizar el cálculo de la suma de dos arreglos unidimensionales utilizando la GPU y cómo almacena los resultados en un tercer arreglo.
Primero en el Código 6.1 se declara una constante N con un valor de 10000 que servirá para definir la longitud de los arreglos a [ ] y b [ ] que contienen los valores a sumar y que se guardaran en un arreglo c [ ].
#define N 10000