El límite de CUDA parece ser alcanzado, pero ¿qué límite es eso?

Tengo un progtwig CUDA que parece estar llegando a algún tipo de límite de algún recurso, pero no puedo entender cuál es ese recurso. Aquí está la función kernel:

__global__ void DoCheck(float2* points, int* segmentToPolylineIndexMap, int segmentCount, int* output) { int segmentIndex = threadIdx.x + blockIdx.x * blockDim.x; int pointCount = segmentCount + 1; if(segmentIndex >= segmentCount) return; int polylineIndex = segmentToPolylineIndexMap[segmentIndex]; int result = 0; if(polylineIndex >= 0) { float2 p1 = points[segmentIndex]; float2 p2 = points[segmentIndex+1]; float2 A = p2; float2 a; ax = p2.x - p1.x; ay = p2.y - p1.y; for(int i = segmentIndex+2; i = 0); float2 p3 = points[i]; float2 p4 = points[i+1]; float2 B = p4; float2 b; bx = p4.x - p3.x; by = p4.y - p3.y; float2 c; cx = Bx - Ax; cy = By - Ay; float2 b_perp; b_perp.x = -by; b_perp.y = bx; float numerator = dot(b_perp, c); float denominator = dot(b_perp, a); bool isParallel = (denominator == 0.0); float quotient = numerator / denominator; float2 intersectionPoint; intersectionPoint.x = quotient * ax + Ax; intersectionPoint.y = quotient * ay + Ay; result = result | (isLegit && !isParallel && intersectionPoint.x > min(p1.x, p2.x) && intersectionPoint.x > min(p3.x, p4.x) && intersectionPoint.x < max(p1.x, p2.x) && intersectionPoint.x  min(p1.y, p2.y) && intersectionPoint.y > min(p3.y, p4.y) && intersectionPoint.y < max(p1.y, p2.y) && intersectionPoint.y < max(p3.y, p4.y)); } } output[segmentIndex] = result; } 

Aquí está la llamada para ejecutar la función kernel:

 DoCheck<<>>( (float2*)devicePoints, deviceSegmentsToPolylineIndexMap, numSegments, deviceOutput); 

Los tamaños de los parámetros son los siguientes:

  • devicePoints = 22,464 float2s = 179,712 bytes
  • deviceSegmentsToPolylineIndexMap = 22,463 ints = 89,852 bytes
  • numSegments = 1 int = 4 bytes
  • deviceOutput = 22,463 ints = 89,852 bytes

Cuando ejecuto este núcleo, bloquea la tarjeta de video. Parece que estoy alcanzando algún tipo de límite, porque si ejecuto el kernel usando DoCheck<<>>(...); , funciona. Para que quede claro, los parámetros son los mismos, solo el número de bloques es diferente.

¿Alguna idea de por qué uno bloquea el controlador de video y el otro no? El que falla parece estar todavía dentro del límite de la tarjeta en el número de bloques.

Actualizar Más información sobre la configuración de mi sistema:

  • Tarjeta de video: nVidia 8800GT
  • Versión de CUDA: 1.1
  • Sistema operativo: Windows Server 2008 R2

También lo probé en una computadora portátil con la siguiente configuración, pero obtuve los mismos resultados:

  • Tarjeta de video: nVidia Quadro FX 880M
  • Versión de CUDA: 1.2
  • Sistema operativo: Windows 7 de 64 bits

El recurso que se está agotando es el tiempo. En todas las plataformas actuales de CUDA, el controlador de pantalla incluye un temporizador de vigilancia que matará a cualquier núcleo que tarda más de unos pocos segundos en ejecutarse. La ejecución del código en una tarjeta que ejecuta una pantalla está sujeta a este límite.

En las plataformas WDDM Windows que está utilizando, existen tres posibles soluciones / soluciones alternativas:

  1. Obtenga una tarjeta Telsa y use el controlador TCC, que elimina el problema completamente
  2. Intente modificar la configuración del registro para boost el límite del temporizador (google para la clave de registro TdrDelay para obtener más información, pero no soy un usuario de Windows y no puedo ser más específico que eso)
  3. Modifique su código de kernel para que sea “reentrante” y procese la carga de trabajo paralela de datos en varios lanzamientos de núcleo en lugar de uno. La sobrecarga de inicio del kernel no es tan grande y el procesamiento de la carga de trabajo en varias ejecuciones del núcleo suele ser bastante fácil de lograr, según el algoritmo que esté utilizando.