Pregunta

Me interesa saber si algún algoritmo común (clasificación, búsqueda, gráficos, etc.) se ha portado a OpenCL (o cualquier lenguaje de GPU), y cómo se compara el rendimiento con el mismo algoritmo ejecutado por la CPU. Estoy específicamente interesado en los resultados (números).

¡Gracias!

¿Fue útil?

Solución

Hay bastantes muestras de este tipo de cosas en el sitio web de NVidia. Tenga en cuenta que algunas cosas, como la clasificación, necesitan algoritmos especiales para un paralelismo eficiente y pueden no ser tan eficientes como un algoritmo no roscado en un solo núcleo.

Otros consejos

Las GPU son hardware altamente especializado diseñado para realizar un pequeño conjunto de tareas muy bien y muy paralelizado. Esto es básicamente aritmético (particularmente matemática de coma flotante de precisión simple, aunque las GPU más nuevas funcionan bastante bien con doble precisión). Como tal, solo son adecuados para algoritmos particulares. No estoy seguro de si la clasificación se ajusta a esa categoría (al menos en el caso general).

Ejemplos más comunes son la fijación de precios de instrumentos financieros, grandes cantidades de matemática matricial e incluso derrotando el cifrado (por fuerza bruta). Dicho esto, encontré Clasificación rápida de GPU paralela utilizando un algoritmo híbrido .

Otro ejemplo comúnmente citado es ejecutando SETI @ HOME en una GPU Nvidia pero compara manzanas con naranjas Las unidades de trabajo para las GPU son diferentes (y muy limitadas) en comparación con lo que normalmente hacen las CPU.

Eche un vistazo a empuje :

  

Thrust es una biblioteca CUDA de paralelo   algoritmos con una interfaz   parecido a la plantilla estándar de C ++   Biblioteca (STL). El empuje proporciona un   Interfaz flexible de alto nivel para GPU   programación que mejora enormemente   productividad del desarrollador.

TENGA CUIDADO, MUY TENGA CUIDADO de cualquier número de rendimiento citado para GPGPU. A mucha gente le gusta publicar números realmente impresionantes que no tienen en cuenta el tiempo de transferencia necesario para obtener los datos de entrada de la CPU a la GPU y los datos de salida, ambos pasando por un cuello de botella PCIe.

El cambio de tamaño de la imagen debe ser común en muchos sitios web que aceptan cargas de imágenes.

Cambiar el tamaño de una imagen jpeg de 2600ish x 2000ish 2MB (a 512x512) tomó 23.5 milisegundos en C # con opciones de calidad absoluta más baja y muestreo de vecino más cercano. La función utilizada era graphics.DrawImage () basada en una. El uso de la CPU también fue% 21.5.

Obteniendo " matriz de bytes rgba " la extracción en el lado C # y enviarla a la GPU y cambiar el tamaño de la GPU y obtener resultados de nuevo en una imagen tomó 6.3 milisegundos y el uso de la CPU fue% 12.7. Esto se hizo con un% 55 gpu más barato con solo 320 núcleos.

Solo multiplicador de aceleración 3.73X.

El factor limitante aquí fue enviar los datos extraídos de 20 MB rgb (¡jpeg es solo 2 MB!) a la GPU. ¡Esa parte que consumió mucho tiempo fue casi el 90% del tiempo total, incluida la extracción de la matriz de bytes laterales C #! Así que supongo que habría una aceleración de aproximadamente 30X al menos si la parte de extracción también se pudiera hacer en la GPU.

30X no es malo.

¡Entonces podría canalizar la capa de extracción con la capa de cambio de tamaño para ocultar la latencia de copia de memoria para obtener aún más velocidad! Esto podría ser 40X-50X.

Luego aumente la calidad del muestreo (como bicubic en lugar del vecino más cercano), tiene aún más ventaja en el lado de la GPU. Agregar un filtro gaussiano 5x5 agregó solo 0.77 milisegundos. Además, la CPU obtendría un mayor tiempo, especialmente si los parámetros gaussianos necesarios son diferentes de la implementación de C # .Net.


Incluso si no está satisfecho con la relación de aceleración, la descarga a la GPU y tener un "núcleo libre" en la CPU sigue siendo ventajoso para empujar más trabajo a ese servidor.

Ahora agregue el hecho de los niveles de consumo de energía de la GPU (30W frente a 125W en este ejemplo), es mucho más ventajoso.


La CPU difícilmente podría ganar

 C[i]=A[i]+B[i]

puntos de referencia cuando ambas partes se ejecutan en códigos optimizados y aún puede descargar la mitad de los arreglos a la GPU y terminar más rápido usando CPU + GPU al mismo tiempo.


GPU no está construido para trabajos no uniformes. Las GPU tienen tuberías profundas, por lo que permanecer de pie después de una parada debido a la ramificación lleva demasiado tiempo. Además, el hardware tipo SIMD lo obliga a hacer lo mismo en todos los elementos de trabajo. Cuando un elemento de trabajo hace algo diferente al grupo, pierde la pista y agrega burbujas en toda la tubería SIMD o simplemente otros esperan el punto de sincronización. Por lo tanto, el bifurcación afecta tanto las áreas de tubería profundas como las anchas y lo hace aún más lento que la CPU en condiciones perfectamente caóticas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top