2010-12-10 6 views
6

Estoy trabajando en un proyecto con CUDA. Para entenderlo, tengo el siguiente código.Principiante CUDA - Incremento var simple no funciona

#include <iostream> 

using namespace std; 

__global__ void inc(int *foo) { 
    ++(*foo); 
} 

int main() { 
    int count = 0, *cuda_count; 
    cudaMalloc((void**)&cuda_count, sizeof(int)); 
    cudaMemcpy(cuda_count, &count, sizeof(int), cudaMemcpyHostToDevice); 
    cout << "count: " << count << '\n'; 
    inc <<< 100, 25 >>> (&count); 
    cudaMemcpy(&count, cuda_count, sizeof(int), cudaMemcpyDeviceToHost); 
    cudaFree(cuda_count); 
    cout << "count: " << count << '\n'; 
    return 0; 
} 

salida es

count: 0 
count: 0 

Cuál es el problema?

¡Gracias de antemano!

+0

probablemente debería trabajar a través de algunos de los ejemplos de la guía de programación. Su sintaxis tiene discrepancias con lo que se sugiere en la guía de programación. – Marm0t

Respuesta

6

he encontrado la solución. Solo tuve que usar una función atómica, es decir, una función que se ejecuta sin interferencia de otros hilos. En otras palabras, ningún otro hilo puede acceder a una dirección específica hasta que la operación sea completa.

Código:

#include <iostream> 

using namespace std; 

__global__ void inc(int *foo) { 
    atomicAdd(foo, 1); 
} 

int main() { 
    int count = 0, *cuda_count; 
    cudaMalloc((void**)&cuda_count, sizeof(int)); 
    cudaMemcpy(cuda_count, &count, sizeof(int), cudaMemcpyHostToDevice); 
    cout << "count: " << count << '\n'; 
    inc <<< 100, 25 >>> (cuda_count); 
    cudaMemcpy(&count, cuda_count, sizeof(int), cudaMemcpyDeviceToHost); 
    cudaFree(cuda_count); 
    cout << "count: " << count << '\n'; 
    return 0; 
} 

Salida:

count: 0 
count: 2500 

gracias por hacer que me diera cuenta del error que estaba cometiendo.

8

Debe pasar cuda_count a la función kernel. Aparte de eso, todos tus hilos intentan incrementar la misma ubicación de memoria. El efecto de eso no está bien definido (al menos una escritura tendrá éxito, pero más de una puede).

Debe impedir que sólo dejando un hilo de ejecutar la obra:

__global__ void inc(int *foo) { 
    if (blockIdx.x == 0 && threadIdx.x == 0) 
    ++*foo; 
} 

(no probado)

+0

¡Qué fracaso mío! Sin embargo, la salida todavía está mal. Me da 1, en cambio, el 2500 esperado. –

+5

@Renato: así no es como funciona CUDA. Vea mi respuesta actualizada: simplemente no está definido escribir en la misma ubicación de memoria desde diferentes subprocesos. Lo que quieres es una llamada operación de recopilación. Implementar esto no es trivial. –

+0

Intenté su solución rápida, pero la salida fue 2. –

0

El problema con su código es que está pasando al puntero del kernel del dispositivo al puntero para contar. No puntero para contar. Una '&' demasiado

Esta línea

inc <<< 100, 25 >>> (&count); 

En caso de ser

inc <<< 100, 25 >>> (count); 
Cuestiones relacionadas