__global__ void sumaVector(long *v1, long *v2, long *v3, long N) {
int threadId = blockIdx.x * blockDim.x + threadIdx.x;
while (threadId < N) {
v3[threadId] = v1[threadId] + v2[threadId];
threadId += blockDim.x * gridDim.x;
}
}
int main(int argc, char** argv) {
long N = 9000000; // 9 millones
long *v1, *v2, *v3;
v1 = (long *) malloc(N * sizeof(long));
v2 = (long *) malloc(N * sizeof(long));
v3 = (long *) malloc(N * sizeof(long));
for (long i = 0; i < N; i++) {
// datos de prueba
v1[i] = 10;
v2[i] = 11;
}
printf("%ld", v1[1000001]); //OK
long *dv1, *dv2, *dv3;
cudaMalloc((void**) &dv1, N * sizeof(long));
cudaMalloc((void**) &dv2, N * sizeof(long));
cudaMalloc((void**) &dv3, N * sizeof(long));
// copiando memoria a la GPGPU
cudaMemcpy(dv1, v1, N * sizeof(long), cudaMemcpyHostToDevice);
cudaMemcpy(dv2, v2, N * sizeof(long), cudaMemcpyHostToDevice);
// número de bloques
int B = 1024;
int T = 1024;
// Llamando a ejecutar el kernel
sumaVector<<<B, T>>>(dv1, dv2, dv3, N);
// copiando el resultado a la memoria Host
cudaMemcpy(v3, dv3, N * sizeof(long), cudaMemcpyDeviceToHost);
cudaFree(dv1);
cudaFree(dv2);
cudaFree(dv3);
printf("%ld", v3[900001]); //OK
return (EXIT_SUCCESS);
}
Características importantes a tomar en cuenta
- Este cálculo se realiza en dimensión 1D.
- Se define la llamada del kernel para 1024 bloques y cada bloque con 1024 threads. Por lo tanto la GPGPU ejecutará 1,048,576 threads.
- El vector tiene un tamaño de 9 millones de elementos (se usó valores long para disponer en cualquier caso de números grandes).
- Debido a que el número de elementos excede el número de threads en el kernel, la codificación de éste incluye un ciclo que indica que se deberá estar realizando hasta que se terminen de calcular las 9 millones de veces.
No hay comentarios:
Publicar un comentario