Ejercicios de CUDA en C
Ejercicios básicos
Orden de ejecución
Ejemplo
En este código mostraremos como ejecutar la función primero en la GPU, y luego en la CPU.
En este otro caso, primero se ejecutará en la CPU y posteriormente en la GPU.
Ejecución de hilos y bloques en un Kernel
Ejemplo
En este primer ejemplo, vamos a ejecutar 5 hilos en un único bloque para un Kernel.
En este otro ejemplo, vamos a ejecutar 5 hilos en 5 bloques diferentes de un mismo Kernel.
Utilizar índices específicos de hilos y bloques en un Kernel
Ejemplo
Aceleración de un bucle con un único bloque de subprocesos
Ejemplo
Aceleración de un bucle con varios bloques de subprocesos
Ejemplo
Manipulación de arrays en el host y device
Ejemplo
Aceleración de un bucle con una configuración de ejecución no coincidente
Ejemplo
Utilizar un bucle Grid-Stride para manipular un array mayor que la cuadrícula de los bloques
Ejemplo
Manejo de errores
Ejemplo
El error obtenido es el siguiente: invalid configuration argument
Y vemos que se trata de la configuración del Kernel donde el número de hebras por bloque supera el máximo de 1 Giga-Bloque. Por lo que hay que cambiar al máximo permitido:
Acelerar la suma de vectores
Ejemplo
Acelerar la multiplicación de matrices 2D
Ejemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
Acelerar una aplicación de conductividad térmica
Ejemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
Ejercicios avanzados
Perfilar una aplicación con nsys
Podemos utilizar el comando !nsys profile --stats=true ./kernel para obtener
información sobre dicho kernel. Entre la información proporcionada, se encuentra el
tiempo medio de ejecución del kernel po lo que sería muy útil para hacer evaluaciones
del mejor reparto de bloques y hebras para el problema concreto.
Optimización
Por ejemplo, si tenemos datos con tamaños de \(2^{24} = 2^{25} = 2^{10} \cdot 2^{10} \cdot 2^{5}\), podemos tener como máximo 1024 hebras por bloque, quedando \(2^{15}\) hebras que las repartiremos conformando \(2^{25}/1024 = 32768\) bloques. En total tendríamos \(1024 \cdot 32768 = 33554432\) hebras totales.
Consultar especificaciones de la GPU
Ejemplo
Optimizar la suma de vectores con cuadrículas del tamaño del número de SMs de la GPU
Ejemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
Prefetch/precarga de memoria
Ejemplo
Al utilizar precarga de memoria, obtenemos menos transferencias de memoria pero con mayor contenido además de una reducción en el tiempo de ejecución del Kernel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |