NDRange, o N-Dimensional Range, es una abstracción clave utilizada en frameworks de computación paralela como OpenCL y CUDA para describir el espacio de ejecución de un kernel. Representa un conjunto multidimensional de elementos de trabajo (work-items) que ejecutarán el mismo código del kernel de forma concurrente. Un NDRange se define por dos conjuntos de dimensiones: el 'global work size', que especifica el número total de elementos de trabajo a ejecutar en cada dimensión, y el 'local work size' (o 'work-group size'), que define cómo estos elementos de trabajo se agrupan en 'work-groups' para su ejecución en unidades de procesamiento (como 'compute units' o 'streaming multiprocessors'). La organización multidimensional permite mapear de forma natural problemas con estructuras de datos inherentemente N-dimensionales, como el procesamiento de imágenes (2D) o simulaciones físicas (3D).
NDRange es central en la programación de GPGPU (General-Purpose computing on Graphics Processing Units). En OpenCL, los desarrolladores definen explícitamente el 'global work size' y, opcionalmente, el 'local work size' para cada dimensión al encolar un kernel. Por ejemplo, para procesar una imagen de 1920x1080 píxeles, el 'global work size' podría ser [1920, 1080] y el 'local work size' podría ser [16, 16], indicando que cada 'work-group' procesará un bloque de 16x16 píxeles. CUDA utiliza un concepto similar con 'grid dimensions' y 'block dimensions', donde el 'grid' es análogo al 'global work size' y el 'block' al 'local work size'. Otros frameworks como SYCL y ROCm también adoptan esta abstracción para la orquestación de la ejecución paralela en aceleradores heterogéneos.
Para un arquitecto de sistemas, comprender NDRange es crucial para diseñar soluciones de alto rendimiento en entornos heterogéneos. La elección del 'local work size' (o 'work-group size') impacta directamente la eficiencia de la ejecución: un tamaño óptimo puede maximizar la utilización de recursos de hardware, como la memoria compartida ('shared memory' en CUDA, 'local memory' en OpenCL) y los registros, así como la ocultación de latencia. Un tamaño subóptimo puede llevar a 'underutilization' de los 'compute units' o a 'overheads' de sincronización. Los arquitectos deben considerar los 'trade-offs' entre la granularidad del paralelismo, el uso de memoria en chip y la complejidad de la sincronización. La correcta definición del NDRange es fundamental para escalar algoritmos a través de diferentes arquitecturas de GPU y para lograr el máximo rendimiento en cargas de trabajo intensivas en cómputo, como inteligencia artificial, procesamiento de señales y simulaciones científicas.