2012-09-29 10 views
11

Soy bastante nuevo en la programación de GPU, pero debido a que tengo una tarea computacionalmente intensiva, he recurrido a la GPU para obtener posibles mejoras de rendimiento.ArrayFire versus programación cruda CUDA?

He intentado reescribir mi programa con la versión ArrayFire Free. De hecho es más rápido que mi rutina de CPU con multi-threading habilitado, pero no en el grado esperado (es decir, < 100% de aceleración), y los resultados devueltos no son correctos (< 1% de error en comparación con la rutina de la CPU, suponiendo los resultados de la rutina de la CPU son correctos).

Mi tarea es principalmente operaciones de matemática float-32 con elementos en matrices grandes (tamaño 300MB-500MB), con pocos if-thens/switch-cases etc. Supongo que el cuello de botella de rendimiento es probablemente el ancho de banda entre CPU y GPU memoria ya que hay mucha lectura de datos, etc. La GPU que probé es una GeForce 580GTX con 3 GB de memoria de video.

¿Todavía hay espacio significativo para la optimización si escribo código CUDA sin procesar (con CUBLAS, etc., y la optimización promedio) en lugar de usar ArrayFire para mi tarea? Leí algunas guías de optimización de NVIDIA; parece que hay algunos trucos de acceso a la memoria para un acceso más rápido a los datos y para reducir los conflictos bancarios. ¿ArrayFire usa estos trucos generales automáticamente o no?

Respuesta

16

Gracias por el mensaje. Me alegra saber que los resultados iniciales dieron un poco de velocidad. Trabajo en ArrayFire y puedo responder aquí en sus preguntas.

En primer lugar, el código es realmente necesario aquí para que cualquiera pueda ayudar con la especificidad. ¿Puedes compartir el código que escribiste?

En segundo lugar, debe pensar en CUDA y ArrayFire de la siguiente manera: CUDA es una forma de programar la GPU que le proporciona la capacidad de escribir cualquier código de la GPU que desee. Pero hay una gran diferencia entre el código CUDA ingenuo (a menudo más lento que la CPU) y el código CUDA experto, de replanteo y optimizado a mano. ArrayFire (y algunas otras bibliotecas de GPU como CUBLAS) tienen muchos años-hombre de optimizaciones vertidas en ellos, y generalmente van a dar mejores resultados de los que la mayoría de la gente normal tendrá tiempo de lograr por sí misma. Sin embargo, también existe una variabilidad en la forma en que alguien usa ArrayFire (u otras bibliotecas). Hay variables que pueden y deben modificarse en el uso de las llamadas de la biblioteca ArrayFire para obtener el mejor rendimiento. Si publica su código, podemos ayudar a compartir algunos de ellos aquí.

En tercer lugar, ArrayFire utiliza CUBLAS en las funciones que dependen de BLAS, por lo que no es probable que vea mucha diferencia al usar CUBLAS directamente.

En cuarto lugar, sí, ArrayFire utiliza todas las optimizaciones que están disponibles en la Guía de programación NVIDIA CUDA para (por ejemplo, transferencia de datos más rápida y conflictos de banco de memoria reducidos como usted menciona). Ahí es donde se concentra la mayor parte del desarrollo de ArrayFire, en la optimización de ese tipo de cosas.

Finalmente, las discrepancias en los datos que ha notado se deben probablemente a la naturaleza de la computación CPU vs GPU. Dado que son dispositivos diferentes, a menudo verá resultados ligeramente diferentes. No es que la CPU ofrezca mejores resultados que la GPU, sino que ambos trabajan con cantidades finitas de precisión de maneras ligeramente diferentes. Si usa una precisión simple en lugar de la doble, puede considerar eso. El código de publicación nos permitirá ayudarnos con eso también.

Feliz de ampliar mi respuesta una vez que se publique el código.

+0

¿No cumplen ambas con las especificaciones IEEE? Asumo que usar 'Single Precision' en ambos debería dar el mismo resultado. De nuevo, suponiendo que el orden del cálculo sea el mismo también. – Royi