Cuda gridDim y blockDim


Answers

Parafraseado de la Guía de Programación de CUDA :

gridDim: esta variable contiene las dimensiones de la grilla.

blockIdx: esta variable contiene el índice de bloque dentro de la grilla.

blockDim: esta variable y contiene las dimensiones del bloque.

threadIdx: esta variable contiene el índice de subprocesos dentro del bloque.

Parece que estás un poco confundido acerca de la jerarquía de hilos que tiene CUDA; en pocas palabras, para un núcleo habrá 1 cuadrícula, (que siempre visualizo como un cubo tridimensional). Cada uno de sus elementos es un bloque, de modo que una grilla se declara como dim3 grid(10, 10, 2); tendría 10 * 10 * 2 bloques en total. A su vez, cada bloque es un cubo tridimensional de hilos.

Dicho esto, es común usar solo la dimensión x de los bloques y las cuadrículas, que es lo que parece que está haciendo el código de tu pregunta. Esto es especialmente importante si está trabajando con matrices 1D. En ese caso, su línea tid+=blockDim.x * gridDim.x en efecto sería el índice único de cada subproceso dentro de su grilla. Esto es porque tu blockDim.x sería el tamaño de cada bloque, y tu gridDim.x sería la cantidad total de bloques.

Entonces, si lanzas un kernel con parámetros

dim3 block_dim(128,1,1);
dim3 grid_dim(10,1,1);
kernel<<<grid_dim,block_dim>>>(...);

luego, en su kernel tenía threadIdx.x + blockIdx.x*blockDim.x que efectivamente tendría:

threadIdx.x range from [0 ~ 128)

blockIdx.x range from [0 ~ 10)

blockDim.x equal to 128

gridDim.x equal to 10

Por lo tanto, al calcular threadIdx.x + blockIdx.x*blockDim.x , tendría valores dentro del rango definido por: [0, 128) + 128 * [1, 10) , lo que significaría que sus valores de tid van desde {0 , 1, 2, ..., 1279}. Esto es útil para cuando quiere mapear hilos a tareas, ya que esto proporciona un identificador único para todos sus hilos en su kernel.

Sin embargo, si tiene

int tid = threadIdx.x + blockIdx.x * blockDim.x;
tid += blockDim.x * gridDim.x;

entonces esencialmente tendrás: tid = [0, 128) + 128 * [1, 10) + (128 * 10) , y tus valores de tid van desde {1280, 1281, ..., 2559} Estoy no estoy seguro de dónde sería relevante, pero todo depende de su aplicación y de cómo asigne sus hilos a sus datos. Este mapeo es bastante central para cualquier lanzamiento de kernel, y tú eres quien determina cómo se debe hacer. Cuando ejecuta su kernel, especifica las dimensiones de la cuadrícula y del bloque, y usted es quien debe imponer la asignación a sus datos dentro de su kernel. Siempre y cuando no excedas los límites de tu hardware (para tarjetas modernas, puedes tener un máximo de 2 ^ 10 hilos por bloque y 2 ^ 16 - 1 bloque por hilo)

Question

Obtengo lo que es BlockDim ... Pero tengo un problema con gridDim. Blockdim da el tamaño del bloque, pero ¿qué es gridDim? En Internet dice gridDim.x da la cantidad de bloques en la coordenada x.

¿Cómo puedo saber qué proporciona blockDim.x * gridDim.x ?

¿Cómo puedo saber cuántos valores de gridDim.x hay en la línea x?

Por ejemplo, considere el siguiente código:

int tid = threadIdx.x + blockIdx.x * blockDim.x;
int cacheIndex = threadIdx.x;
double temp = a[tid];
tid += blockDim.x * gridDim.x;
while (tid < count) {
if (a[tid] > temp)
temp = a[tid];
tid += blockDim.x * gridDim.x;
}

Sé que tid comienza con 0. El código tiene tid+=blockDim.x * gridDim.x . ¿Qué es tid ahora después de esta operación?




Links



Tags

cuda