Tabla de Contenidos
Introducción
Se implementa un ejemplo sencillo en el que se inicializa un vector. Cada cudaThread escribirá en una posición del vector su identificador.
Aplicación paso a paso
Includes necesarios
Para poder hacer uso de CUDA es necesario incluir:
#include <stdio.h> // No es necesaria pero la incluyo para poder usar printf #include <cuda.h>
Kernel: código ejecutado en la GPU
Lo primero es necesario añadir a la cabecera global para indicar que es código ejecutado en la GPU. Además debemos incluir como parámetro el puntero al vector donde vamos a escribir. Calculamos el identificador del cudaThread usando la expresión threadIdx.x + threadIdx.y * gridDim.x y escirbimos en identificador calculado en la posición que indica el identificador.
__global__ void test(int * data) { int id = threadIdx.x + threadIdx.y * gridDim.x; data[id] = id; }
El main
Los pasos a seguir en el main son:
- Crear las estructuras en la CPU y en la GPU.
- Creamos un vector estático en la CPU.
- Creamos un vector en la GPU.
- Llamamos a la función, poniendo el número de bloques, en este caso 1 y el número de cudaThreads en este caso 1024.
- Recogemos los resultados y comprobamos que son correctos.
int main() { // Vector que reside en la CPU y que usaremos para comprobar que los resultados son correctos int res[1024]; // Puntero para reservar el vector en la GPU int * dbg; // Reserva del vector de 1024 enteros en la GPU cudaMalloc((void**)&dbg, sizeof(int) * 1024); // LLamada a la función CUDA test<<<1, 1024>>>(dbg); // Copia del vector residente en la GPU al vector residente en la CPU cudaMemcpy(res, dbg, sizeof(int) * 1024, cudaMemcpyDeviceToHost); // Comprobando si el resultado es correcto for (int i = 0; i != 1024; i++) printf("%3d %f\n", i + 1, res[i]); // Liberando el vector cudaFree(dbg); return 0; }
Compilando y Ejecutando la aplicación
Para compilar la aplicación será necesario simplemente con usar el siguiente comando:
nvcc --compiler-options -Wall -o <nombre_ejecutable> <nombre_fuente.cu>
- nvcc: es el compilador de NVIDIA.
- –compiler-options -Wall: fuerza al compilador de C a darnos todos los warnings que encuentre.
Si la versión del gcc es superior o igual a la 4.5 debemos instalar una versión anterior.
Una posible solución es instalarla en /opt/gcc-vieja y a la hora de compilar indicarlo con la opción –compiler-bindir.
Un ejemplo:
nvcc --compiler-options -Wall --compiler-bindir /opt/gcc-4.4.6/bin -o <nombre_ejecutable> <nombre_fuente.cu>