Siempre he trabajado con la memoria lineal compartida (carga, tienda, vecinos de acceso), pero he hecho una prueba sencilla en 2D para estudiar los conflictos bancarias que los resultados me han confundido.2D memoria compartida dispuesta en CUDA
El siguiente código de leer los datos de una matriz de memoria global de dimensiones a la memoria compartida y copiarlo desde la memoria compartida de la memoria global.
__global__ void update(int* gIn, int* gOut, int w) {
// shared memory space
__shared__ int shData[16][16];
// map from threadIdx/BlockIdx to data position
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
// calculate the global id into the one dimensional array
int gid = x + y * w;
// load shared memory
shData[threadIdx.x][threadIdx.y] = gIn[gid];
// synchronize threads not really needed but keep it for convenience
__syncthreads();
// write data back to global memory
gOut[gid] = shData[threadIdx.x][threadIdx.y];
}
El perfilador visual informó conflictos de memoria compartida. Los próximos conflictos código de evitar thouse (sólo muestran las diferencias)
// load shared memory
shData[threadIdx.y][threadIdx.x] = gIn[gid];
// write data back to global memory
gOut[gid] = shData[threadIdx.y][threadIdx.x];
Este comportamiento me ha confundido porque en la programación de los procesadores masivamente paralelos. Un enfoque práctico que podemos leer:
Los elementos de matriz en C y CUDA se colocan en las ubicaciones direccionadas linealmente de acuerdo con la convención principal de filas. Es decir, los elementos de la fila 0 de una matriz se colocan primero en orden en ubicaciones consecutivas.
¿Está relacionado con el arragmento de memoria compartida? o con índices de hilos? Tal vez me estoy perdiendo algo?
La configuración del núcleo es el siguiente:
// kernel configuration
dim3 dimBlock = dim3 (16, 16, 1);
dim3 dimGrid = dim3 (64, 64);
// Launching a grid of 64x64 blocks with 16x16 threads -> 1048576 threads
update<<<dimGrid, dimBlock>>>(d_input, d_output, 1024);
Gracias de antemano.
Podría agregar las dimensiones del bloque que está utilizando. Supongo que es (16, 16, 1), pero es bueno tenerlo confirmado antes de responder. – talonmies
@talonmies Agregué la configuración/lanzamiento del kernel a la pregunta. Como ha comentado, estoy usando un bloque (16, 16, 1) – pQB