2011-04-19 55 views
20

Tengo un kernel que llama a dispositivo dentro de una sentencia if. El código es el siguiente:CUDA: Llamar a una función __device__ desde un kernel

__device__ void SetValues(int *ptr,int id) 
{ 
    if(ptr[threadIdx.x]==id) //question related to here 
      ptr[threadIdx.x]++; 
} 

__global__ void Kernel(int *ptr) 
{ 
    if(threadIdx.x<2) 
     SetValues(ptr,threadIdx.x); 
} 

En los hilos del núcleo 0-1 setValues ​​de llamadas al mismo tiempo. ¿Qué pasa después de eso? Quiero decir que ahora hay 2 llamadas concurrentes a SetValues. ¿Cada llamada de función se ejecuta en serie? ¿Entonces se comportan como 2 llamadas a la función kernel?

Respuesta

22

CUDA realmente incluye todas las funciones por defecto (aunque Fermi y las arquitecturas más recientes también admiten un ABI apropiado con punteros a funciones y llamadas a funciones reales). Por lo que su código de ejemplo se compila a algo como esto

__global__ void Kernel(int *ptr) 
{ 
    if(threadIdx.x<2) 
     if(ptr[threadIdx.x]==threadIdx.x) 
      ptr[threadIdx.x]++; 
} 

ejecución se produce en paralelo, al igual que el código normal. Si diseñas una carrera de memoria en una función, no hay un mecanismo de serialización que pueda salvarte.

+0

tengo una tarjeta fermi. ¿Esto significa que la función no está en línea? por lo tanto, el threadIdx.x en SetValues ​​son todos los hilos y no solo los hilos 0 y 1? – scatman

+1

Las funciones todavía están en línea por defecto en Fermi. Creo que entiendo de lo que realmente está preguntando ahora, cuál es el alcance de las variables de subproceso integradas (como threadIdx) dentro de las funciones de __device__. ¿Me estoy calentando? – talonmies

+0

sí, esa es mi pregunta. pero como las funciones de __device__ están en línea ... entonces supongo que el alcance de los hilos es el mismo que se usa usando <<< bloques, hilos >>> pero debido a la rama solo los hilos 0 y 1 ejecutan ptr [threadIdx.x] ++. ¿es esto correcto? – scatman

Cuestiones relacionadas