Hola, en la clase de ayer hablamos de algunos elementos teóricos que pueden estar faltando para resolver el ejercicio 2.
Por esa razón, dejamos este ejercicio como opcional.
En el ejercicio cada hilo debería hacer 3 accesos a memoria: la lectura de su posición en el arreglo de entrada, la lectura de su posición + 4, y la escritura en el arreglo de salida. Es necesario analizar cuántas transacciones de memoria son necesarias para cada acceso realizado por un warp (32 hilos), teniendo en cuenta que las transacciones están alineadas a direcciones múltiplo de 32B.
El primer y tercer acceso a memoria que realiza el warp se resuelve en 4 transacciones de 32B (32 enteros de 4B).
El segundo acceso requiere enteros que se encuentran más allá del cuarto segmento de 32B del primer acceso, por lo que requiere 5 transacciones de 32B, Es decir, por cada warp se realizan 13 transacciones.
CUDA ofrece algunos tipos de datos "vectoriales" que funcionan como un struct de tipos primarios (char, int, float,...).
Por ejemplo, si se interpreta el arreglo de entrada como de tipo int2* cada hilo accede a 2 enteros contiguos del arreglo (el warp accede a 64 enteros en paralelo).
Esto significa que el primer y tercer acceso requerirán 8 segmentos de 32B, y el segundo requerirá 9, 1 menos que los 10 que requiere el primer enfoque (usando dos warp para acceder a 64 enteros). Usando el tipo int4 podría obtenerse un acceso a memoria aún mejor utilizando menos hilos.
Sobre tipos de datos vectoriales se puede consultar https://developer.nvidia.com/blog/cuda-pro-tip-increase-performance-with-vectorized-memory-access/ (en inglés).
Saludos!