He estado investigando procesadores y tarjetas gráficas, y descubrí que las GPU son mucho más rápidas que las CPU. Leí en este artículo , una GPU Nvidia de 2 años superó 14 veces el procesador Intel Core I7 de 3.2GHz en ciertas circunstancias. Si las GPU son tan rápidas, ¿por qué los desarrolladores no las usan para todas las funciones de un juego? ¿Es posible que las GPU hagan algo más que gráficos?
63
GPU is faster than a CPU
Es un falso mito que muchas personas se hacen creer después de ver puntos de referencia basados en problemas específicamente diseñados para GPU (esta clase de problemas se llaman "problemas vergonzosamente paralelos"), vea mi respuesta en esta pregunta de Superusuario: ¿Por qué seguimos usando ¿CPU en lugar de GPU?Respuestas:
"He leído que los autos F1 son más rápidos que los que manejamos en las calles ... ¿por qué la gente no usa autos F1 entonces?" Bueno ... La respuesta a esta pregunta es simple: los autos F1 no pueden romperse o girar tan rápido como la mayoría de los autos (el auto más lento podría vencer a un F1 en ese caso). El caso de las GPU es muy similar, son buenas para seguir una línea recta de procesamiento, pero no son tan buenas cuando se trata de elegir diferentes rutas de procesamiento.
Un programa ejecutado en la GPU tiene sentido cuando debe ejecutarse muchas veces en paralelo, por ejemplo, cuando tiene que mezclar todos los píxeles de la Textura A con píxeles de la Textura B y ponerlos todos en la Textura C. Esta tarea, cuando se ejecuta en una CPU, se procesaría de la siguiente manera:
Pero esto es lento cuando tiene que procesar muchos píxeles, por lo que la GPU en lugar de usar el código anterior, solo usa el siguiente:
y luego completa todos los núcleos con este programa (esencialmente copiando el programa al núcleo), asignando un valor
i
para cada uno. Entonces es de donde viene la magia de la GPU y hacer que todos los núcleos ejecuten el programa al mismo tiempo , haciendo muchas operaciones mucho más rápido de lo que podría hacer el programa lineal de la CPU.Esta forma de trabajar está bien cuando tiene que procesar de la misma manera una gran cantidad de entradas pequeñas, pero es realmente malo cuando tiene que hacer un programa que pueda tener ramificación condicional. Así que ahora veamos qué hace la CPU cuando se trata de alguna verificación de condición:
Esto es muy rápido para que la CPU establezca un índice, pero para que la GPU haga lo mismo, es mucho más complicado. Debido a que la potencia de la GPU proviene de ejecutar la misma instrucción al mismo tiempo (son núcleos SIMD), deben estar sincronizados para poder aprovechar la arquitectura del chip. Tener que preparar la GPU para tratar con sucursales implica más o menos:
Este método puede variar en función de muchas cosas (es decir, algunas muy pequeñaslas sucursales pueden ejecutarse sin la necesidad de esta distinción), pero ahora ya puede ver por qué la ramificación sería un problema. Los cachés de GPU son muy pequeños, no puede simplemente ejecutar un programa desde la VRAM de forma lineal, tiene que copiar pequeños bloques de instrucciones en los núcleos para ejecutarlos y si tiene ramas suficientes, su GPU se detendrá en su mayoría en lugar de ejecutar cualquier código, que no tiene sentido cuando se trata de ejecutar un programa que solo sigue una rama, como la mayoría de los programas, incluso si se ejecuta en múltiples hilos. En comparación con el ejemplo de F1, esto sería como tener que abrir paracaídas de frenado en cada esquina, luego salir del automóvil para empacarlos nuevamente dentro del automóvil hasta la siguiente esquina que desea girar nuevamente o encontrar un semáforo rojo (la siguiente esquina más probable).
Luego, por supuesto, está el problema de que otras arquitecturas sean tan buenas en la tarea de operaciones lógicas, mucho más baratas y más confiables, estandarizadas, más conocidas, eficientes en energía, etc. Las tarjetas de video más nuevas son apenas compatibles con las antiguas sin emulación de software. use diferentes instrucciones asm entre ellas, incluso del mismo fabricante, y que por el momento la mayoría de las aplicaciones de computadora no requieren este tipo de arquitectura paralela, e incluso si las necesitan, pueden usarlas a través de API estándar como OpenCL como mencionado por eBusiness, o a través de las API de gráficos. Probablemente en algunas décadas tendremos GPU que puedan reemplazar las CPU, pero no creo que suceda pronto.
Recomiendo la documentación de la aplicación AMD que explica mucho sobre su arquitectura de GPU y también vi sobre los NVIDIA en los manuales de CUDA, que me ayudaron mucho a entender esto. Todavía no entiendo algunas cosas y puedo estar equivocado, probablemente alguien que sepa más pueda confirmar o negar mis declaraciones, lo que sería genial para todos nosotros.
fuente
the fastest isn't always the fastest
.Las GPU son muy buenas para tareas paralelas. Lo cual es genial ... si estás ejecutando tareas paralelas.
Los juegos son sobre el tipo de aplicación menos paralelizable. Piensa en el ciclo principal del juego. La IA (supongamos que el jugador se maneja como un caso especial de la IA) debe responder a las colisiones detectadas por la física. Por lo tanto, debe ejecutarse después. O al menos, la física necesita llamar a las rutinas de IA dentro de los límites del sistema de física (que generalmente no es una buena idea por muchas razones). Los gráficos no pueden ejecutarse hasta que la física se haya ejecutado, porque la física es lo que actualiza la posición de los objetos. Por supuesto, la IA también debe ejecutarse antes de renderizar, ya que la IA puede generar nuevos objetos. Los sonidos deben ejecutarse después de la IA y los controles del jugador
En general, los juegos pueden enhebrarse de muy pocas maneras. Los gráficos se pueden dividir en un hilo; el bucle del juego puede meter un montón de datos en el hilo de gráficos y decir: renderizar esto. Puede hacer una interpolación básica, de modo que el bucle principal del juego no tenga que estar sincronizado con los gráficos. El sonido es otro hilo; el bucle del juego dice "juega esto", y se juega.
Después de eso, todo comienza a ser doloroso. Si tiene algoritmos de ruta complejos (como los de RTS), puede enhebrarlos. Los algoritmos pueden tardar algunos marcos en completarse, pero al menos serán concurrentes. Más allá de eso, es bastante difícil.
Entonces estás viendo 4 hilos: juego, gráficos, sonido y posiblemente procesamiento de IA a largo plazo. Eso no es mucho. Y eso no es suficiente para las GPU, que pueden tener literalmente cientos de hilos en vuelo a la vez. Eso es lo que les da a las GPU su rendimiento: poder utilizar todos esos hilos a la vez. Y los juegos simplemente no pueden hacer eso.
Ahora, tal vez pueda ser "amplio" para algunas operaciones. Las IA, por ejemplo, suelen ser independientes entre sí. Por lo tanto, puede procesar varias docenas de IA a la vez. Justo hasta que realmente necesites hacerlos dependientes el uno del otro. Entonces estás en problemas. Los objetos de física son igualmente independientes ... a menos que haya una restricción entre ellos y / o choquen con algo. Entonces se vuelven muy dependientes.
Además, existe el hecho de que la GPU simplemente no tiene acceso a la entrada del usuario, que, según tengo entendido, es algo importante para los juegos. Entonces eso tendría que ser proporcionado. Tampoco tiene acceso directo a archivos ni ningún método real de hablar con el sistema operativo; así que de nuevo, tendría que haber algún tipo de forma de proporcionar esto. Ah, y todo ese procesamiento de sonido? Las GPU no emiten sonidos. Entonces esos tienen que volver a la CPU y luego al chip de sonido.
Ah, y la codificación de GPU es terrible. Es difícil acertar, y lo que es "correcto" para una arquitectura de GPU puede estar muy, muy mal para otra. Y eso no es solo cambiar de AMD a NVIDIA; eso podría cambiar de una GeForce 250 a una GeForce 450. Eso es un cambio en la arquitectura básica. Y fácilmente podría hacer que su código no se ejecute bien. C ++ e incluso C no están permitidos; lo mejor que obtienes es OpenCL, que es algo así como C pero sin algunas de las sutilezas. Como la recursividad . Así es: no hay recurrencia en las GPU.
Depuración? Oh, espero que no le gusten las funciones de depuración de su IDE, porque ciertamente no estarán disponibles. Incluso si está usando GDB, bese ese adiós. Tendrá que recurrir a la
printf
depuración ... espere, no hayprintf
GPU. Por lo tanto, tendrá que escribir en las ubicaciones de memoria y hacer que el programa de código auxiliar de su CPU las lea de nuevo.Así es: depuración manual . Buena suerte con eso.
Además, ¿esas útiles bibliotecas que usa en C / C ++? O tal vez eres más un tipo .NET, usando XNA y demás. O lo que sea. No importa, ya que no puedes usar ninguno de ellos en la GPU. Debe codificar todo desde cero. Y si tiene una base de código ya existente, difícil: es hora de reescribir todo ese código.
Así que sí. Es horrible hacerlo para cualquier tipo de juego complejo. Y ni siquiera funcionaría, porque los juegos simplemente no son lo suficientemente paralelos como para ayudar.
fuente
Por qué no es tan fácil de responder: es importante tener en cuenta que las GPU son procesadores especializados que en realidad no están destinados para un uso generalizado como una CPU normal. Debido a esta especialización, no es sorprendente que una GPU pueda superar a una CPU por las cosas para las que fue específicamente diseñada (y optimizada), pero eso no significa necesariamente que pueda reemplazar la funcionalidad y el rendimiento completos de una CPU generalizada.
Sospecho que los desarrolladores no hacen esto por una variedad de razones, que incluyen:
Quieren que los gráficos sean lo más rápidos y de la mejor calidad posible, y el uso de recursos valiosos de GPU podría interferir con esto.
Es posible que deba escribirse un código específico de GPU, y esto probablemente introducirá una complejidad adicional en la programación general del juego (o aplicación) en cuestión.
Una GPU normalmente no tiene acceso a recursos como tarjetas de red, teclados, mouse y joysticks, por lo que de todos modos no es posible manejar todos los aspectos del juego.
En respuesta a la segunda parte de su pregunta: Sí, hay otros usos. Por ejemplo, proyectos como SETI @ Home (y probablemente otros proyectos BOINC) están utilizando GPU (como los de nVidia) para cálculos complejos de alta velocidad:
Ejecute SETI @ home en su GPU NVIDIA
http://setiathome.berkeley.edu/cuda.php
( Me gusta tu pregunta porque plantea una idea interesante ) .
fuente
Las CPU son más flexibles, generalmente es más fácil programarlas, pueden ejecutar subprocesos individuales mucho más rápido.
Si bien las GPU modernas se pueden programar para resolver prácticamente cualquier tarea, solo obtienen una ventaja de velocidad cuando pueden utilizar su arquitectura paralela. Este suele ser el caso con tareas "simples" altamente repetitivas. Gran parte del código que escribimos se ramifica de manera demasiado impredecible para ejecutarse de manera eficiente en una GPU.
Además de todo esto, podría terminar pasando mucho tiempo optimizando el código para diferentes chips gráficos. Si bien OpenCL está disponible para hacer que el mismo código se ejecute en muchos chips gráficos diferentes, intercambiará algunas de las ventajas de velocidad para este lujo.
Desde la perspectiva del programador de juegos, generalmente también queremos que nuestro juego se ejecute en computadoras con tarjetas gráficas menores. Algunos de los chips integrados no tienen la programabilidad requerida, pero si lo hacen son tan lentos que no superarán al procesador por un margen muy grande, incluso para el tipo de trabajos en los que deberían ser buenos. Y, por supuesto, si utilizara una GPU de gama baja para un juego, tomaría la poder de procesamiento muy necesaria de la representación gráfica.
De hecho, las perspectivas son excelentes, pero cuando haces un juego en lugar de descifrar contraseñas, los problemas prácticos en la mayoría de los casos superan los beneficios.
fuente
Las GPU son muy difíciles de programar. Debe buscar cómo ordenar una lista en una GPU . Muchas tesis tienen búsqueda para hacerlo.
Usar una CPU con un subproceso es fácil, usar subprocesos múltiples es más difícil, usar muchas computadoras con una biblioteca paralela ya que PVM o MPI es difícil y usar un gpu es lo más difícil.
fuente
Además de lo que Randolf Richardson respondió, hay algunas funcionalidades que los procesadores de GPU no pueden manejar por sí mismos. Por ejemplo, la CPU procesa algunos de los comandos de administración de memoria gráfica, ya que la GPU no puede manejarlos.
Y hay otra gran razón, la GPU está diseñada para cálculos multiproceso. Esto significa que los fabricantes de GPU pueden agregar fácilmente núcleos siempre que quieran aumentar la potencia de cálculo. Pero hay muchas tareas que no se pueden dividir en problemas más pequeños, como calcular el enésimo número de la serie de Fibonacci . En estas situaciones, la CPU es mucho más rápida ya que está más optimizada para tareas de subproceso único.
fuente
Hay muchas respuestas que sugieren que las GPU son solo más rápidas porque manejan tareas en paralelo. Esto está exagerando un poco el problema. Las GPU pueden ser más eficientes por otros motivos, como poder tener un acceso a la memoria más restrictivo, no tener que admitir tantos tipos de datos, tener un conjunto de instrucciones más eficiente, etc. Las GPU tempranas todavía solo podían dibujar 1 píxel a una vez, pero fue el hecho de que podían hacer 1 cada ciclo lo que era importante.
La verdadera diferencia es que son 2 tipos diferentes de máquinas que están personalizadas para desempeñarse bien en diferentes categorías de tareas que parecen similares pero en realidad son bastante diferentes. Es como comparar un avión con un automóvil. El avión tiene una velocidad máxima mucho más alta, pero tiene más restricciones sobre cómo se puede usar. En las ocasiones en que puede hacer el mismo viaje con cualquier tipo, el avión parece superior.
fuente
Los desarrolladores no utilizan las GPU para todas las funciones que son buenos. Usan CPU para todas las funciones en las que son buenos. ¿Qué te hace pensar que no?
Las GPU son buenas en tareas que se pueden paralelizar masivamente y requieren grandes cantidades de cómputo con bajos requisitos de memoria o alta correlación temporal con solo pequeñas cantidades de toma de decisiones. Esto incluye renderizar imágenes, simulaciones físicas (partículas, colisión, tela, agua, reflejo), etc. Entonces, esto es precisamente para lo que los juegos modernos usan la GPU.
Las CPU son buenas en tareas que no se paralelan bien y requieren grandes cantidades de toma de decisiones. Pueden tolerar altos requisitos de memoria incluso con una correlación temporal moderada. Esto incluye inteligencia artificial, interfaz de usuario, disco y red de E / S, etc. Entonces, esto es precisamente para lo que los juegos modernos usan la CPU.
fuente
Readback es otra razón por la que se me ocurre preferir ocasionalmente la CPU. No en términos de ancho de banda (ya que el ancho de banda de GPU-> CPU no es tanto un problema en el hardware moderno) sino en términos de estancamiento de la tubería. Si necesita recuperar los resultados de un cálculo y hacer algo interesante o útil con ellos, usar la GPU no es una buena elección (en el caso general, habrá casos especiales en los que puede seguir siendo apropiado) ya que la lectura siempre requerirá la GPU para detener lo que sea que esté haciendo, vaciar todos los comandos pendientes y esperar a que se complete la lectura. Esto puede matar el rendimiento en la medida en que no solo elimina el beneficio de usar la GPU, sino que en realidad puede ser considerablemente más lento.
fuente
Este es un hilo viejo, pero este artículo recientemente publicado puede responder esta pregunta. Este documento, publicado en ACM Computing Surveys 2015, muestra que cada una de las CPU y GPU tiene sus ventajas únicas y, por lo tanto, presenta un argumento para alejarse del paradigma de "debate CPU vs GPU" al paradigma de "cómputo colaborativo CPU-GPU".
Una encuesta de las técnicas de computación heterogéneas CPU-GPU
fuente