cuda - ¿Has utilizado con éxito una GPGPU?




hpc (9)

Me interesa saber si alguien ha escrito una aplicación que aproveche una GPGPU utilizando, por ejemplo, nVidia CUDA . Si es así, ¿qué problemas encontraste y qué mejoras de rendimiento lograste en comparación con una CPU estándar?


Answers

Escribí un kernel complejo de multiplicación de matrices que superó la implementación cuBLAS en aproximadamente un 30% para la aplicación para la que lo estaba usando, y una especie de función de vector producto externo que corrió varios órdenes de magnitud que una solución de seguimiento múltiple para el resto de el problema.

Fue un proyecto de último año. Me tomó un año completo.

http://www.maths.tcd.ie/~oconbhup/Maths_Project.pdf


Implementé un cálculo de Monte Carlo en CUDA para algún uso financiero. El código CUDA optimizado es aproximadamente 500 veces más rápido que una implementación de CPU de múltiples subprocesos "podría haber intentado más, pero no realmente". (Comparando un GeForce 8800GT con un Q6600 aquí). Sin embargo, es bien sabido que los problemas de Monte Carlo son embarazosamente paralelos.

Los principales problemas encontrados implican la pérdida de precisión debido a la limitación del chip G8x y G9x a los números de punto flotante de precisión simple IEEE. Con el lanzamiento de los chips GT200, esto podría mitigarse en cierta medida utilizando la unidad de doble precisión, a costa de algún rendimiento. No lo he probado todavía

Además, dado que CUDA es una extensión C, la integración en otra aplicación puede ser no trivial.


Sí. Implementé el Filtro de Difusión Anisotrópico No Lineal usando la API CUDA.

Es bastante fácil, ya que es un filtro que debe ejecutarse en paralelo dada una imagen de entrada. No he encontrado muchas dificultades en esto, ya que solo requería un kernel simple. La aceleración fue de aproximadamente 300x. Este fue mi proyecto final en CS. El proyecto se puede encontrar aquí (está escrito en portugués).

También traté de escribir el algoritmo de segmentación de Mumford & Shah , pero ha sido una tarea difícil de escribir, ya que CUDA todavía está en el principio y ocurren muchas cosas extrañas. Incluso he visto una mejora en el rendimiento agregando un if (false){} en el código O_O.

Los resultados para este algoritmo de segmentación no fueron buenos. Tuve una pérdida de rendimiento de 20x en comparación con un enfoque de CPU (sin embargo, dado que es una CPU, se podría tomar un enfoque diferente que dijera los mismos resultados). Todavía es un trabajo en progreso, pero desafortunadamente dejé el laboratorio en el que estaba trabajando, así que tal vez algún día podría terminarlo.


Implementé Cholesky Factorization para resolver ecuaciones lineales grandes en GPU usando ATI Stream SDK. Mis observaciones fueron

Obtuve aceleración de rendimiento hasta 10 veces.

Trabajando en el mismo problema para optimizarlo más, escalando a múltiples GPU.


He estado desarrollando gpgpu con el SDK de transmisión de ATI en lugar de Cuda. El tipo de ganancia de rendimiento que obtendrás depende de muchos factores, pero el más importante es la intensidad numérica. (Es decir, la proporción de operaciones de cálculo a referencias de memoria).

Una función BLAS nivel-1 o BLAS nivel-2, como agregar dos vectores, solo realiza 1 operación matemática por cada 3 referencias de memoria, por lo que el NI es (1/3). Esto siempre se ejecuta más lento con CAL o Cuda que simplemente hacer en la CPU. La razón principal es el tiempo que lleva transferir los datos de la CPU a la GPU y viceversa.

Para una función como FFT, existen cálculos O (N log N) y referencias de memoria O (N), por lo que NI es O (log N). Si N es muy grande, digamos 1,000,000 es probable que sea más rápido hacerlo en el gpu; Si N es pequeño, digamos 1,000, es casi seguro que sea más lento.

Para una función BLAS nivel-3 o LAPACK como descomposición LU de una matriz, o para encontrar sus valores propios, hay cálculos O (N ^ 3) y referencias de memoria O (N ^ 2), por lo que NI es O (N). Para arreglos muy pequeños, digamos N es un puntaje pequeño, esto aún será más rápido de hacer en la CPU, pero a medida que N aumenta, el algoritmo pasa rápidamente de enlazado a memoria a calculado y el aumento de rendimiento en la CPU aumenta muy con rapidez.

Todo lo que involucre la arithemetic compleja tiene más cálculos que la aritmética escalar, que generalmente dobla la NI y aumenta el rendimiento de la GPU.

http://home.earthlink.net/~mtie/CGEMM%20081121.gif

Aquí está el rendimiento de CGEMM: multiplicación compleja de matrices de precisión simple hecha en un Radeon 4870.


He usado CUDA para varios algoritmos de procesamiento de imágenes. Estas aplicaciones, por supuesto, son muy adecuadas para CUDA (o cualquier paradigma de procesamiento de GPU).

OMI, hay tres etapas típicas cuando se transfiere un algoritmo a CUDA:

  1. Porting inicial: incluso con un conocimiento básico de CUDA, puede portar algoritmos simples en pocas horas. Si tiene suerte, gana un factor de 2 a 10 en rendimiento.
  2. Optimizaciones triviales: esto incluye el uso de texturas para datos de entrada y relleno de matrices multidimensionales. Si tienes experiencia, esto se puede hacer en un día y podría darte otro factor de 10 en rendimiento. El código resultante aún es legible.
  3. Optimizaciones Hardcore: Esto incluye copiar datos a la memoria compartida para evitar latencia de memoria global, voltear el código para reducir el número de registros usados, etc. Puede pasar varias semanas con este paso, pero la ganancia de rendimiento realmente no vale la pena en mayoria de los casos. Después de este paso, su código se ofuscará tanto que nadie lo comprende (incluyéndolo a usted).

Esto es muy similar a la optimización de un código para CPU. Sin embargo, la respuesta de una GPU a las optimizaciones de rendimiento es aún menos predecible que para las CPU.


He escrito aplicaciones triviales, realmente ayuda si puede paralizar cálculos de coma flotante.

Encontré el siguiente curso de un profesor de Urbana Champaign de la Universidad de Illinois y un ingeniero de NVIDIA muy útil cuando comencé: http://courses.ece.illinois.edu/ece498/al/Archive/Spring2007/Syllabus.html ( incluye grabaciones de todas las conferencias).


He estado usando GPGPU para detección de movimiento (Originalmente usando CG y ahora CUDA) y estabilización (usando CUDA) con procesamiento de imagen. He estado recibiendo una aceleración de 10 a 20 veces en estas situaciones.

Por lo que he leído, esto es bastante típico para los algoritmos de datos paralelos.


OpenCL se hace para ese propósito. Proporciona un programa como una cadena y posiblemente lo compila en tiempo de ejecución. Vea los enlaces proporcionados por otro cartel.





cuda gpgpu hpc