#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cuda.h>
#include <math.h>
#define T 1024 // max threads x bloque
#define N 100000
__global__ void sumaVector(int *v1, int *v2, int *v3) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
if (tid < N) {
// debido a que en el último bloque no se realizan todos los threads
v3[tid] = v1[tid] + v2[tid];
}
}
int main(int argc, char** argv) {
int v1[N];
int v2[N];
int v3[N];
int i;
/* inicializando variables con datos foo*/
for (i = 0; i < N; i++) {
v1[i] = i;
v2[i] = i;
v3[i] = 0;
}
for (i = 0; i < N; i++) {
printf(" %d %d \t", v1[i], v2[i]);
if (i % 20 == 0)
printf("\n");
}
int *dv1, *dv2, *dv3;
cudaMalloc((void**) &dv1, N * sizeof(int));
cudaMalloc((void**) &dv2, N * sizeof(int));
cudaMalloc((void**) &dv3, N * sizeof(int));
/* copiando memoria a la GPGPU*/
cudaMemcpy(dv1, v1, N * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(dv2, v2, N * sizeof(int), cudaMemcpyHostToDevice);
/* Calculando el número de bloques*/
float BFloat = (float) N / (float) T;
int B = (int) ceil(BFloat);
/* Llamando a ejecutar el kernel */
sumaVector<<<B, T>>>(dv1, dv2, dv3);
/* copiando el resultado a la memoria Host */
cudaMemcpy(v3, dv3, N * sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(dv1);
cudaFree(dv2);
cudaFree(dv3);
printf("\n");
for (i = 0; i < N; i++) {
printf(" %d=%d", i, v3[i]);
if (i % 40 == 0)
printf("\n");
}
return (EXIT_SUCCESS);
}
Características importantes a tomar en cuenta
- Este cálculo se realiza en dimensión 1D.
- Debido a que el número de threads por dimensión en un bloque es 1024, se define ese valor como T.
- N representa el tamaño del vector, en este caso se definió en 100 mil.
- Debido al tamaño de N, es necesario dividir el trabajo en diferentes bloques, por lo que se realiza el cálculo para la variable B (en este caso seria 100000/1024 =97.65, convertido a 98 bloques).
- Cada bloque es reservado completamente, aunque parte del último bloque no se utilice.
No hay comentarios:
Publicar un comentario