hardware-acceleration tortuga - ¿Qué funciones de OpenGL no están aceleradas por GPU?




download pdf (5)

La pregunta quizás debería ser "¿Qué funciones consumen una cantidad inesperadamente alta de tiempo de CPU?"

Mantener una pila de matriz para proyección y visualización no es algo que la GPU pueda manejar mejor que una CPU (por el contrario ...). Otro ejemplo sería la compilación shader. ¿Por qué debería funcionar esto en la GPU? Hay un analizador, un compilador, ..., que son solo programas de CPU normales como el compilador de C ++.

Las llamadas a funciones potencialmente "peligrosas" son, por ejemplo, glReadPixels , porque los datos se pueden copiar de la memoria del host (= CPU) a la del dispositivo (= GPU) a través del bus limitado. En esta categoría también hay funciones como glTexImage_D o glBufferData .

En términos generales, si desea saber cuánto tiempo de CPU consume una llamada OpenGL, intente comprender su funcionalidad. ¡Y tenga cuidado con todas las funciones, que copian datos desde el host al dispositivo y viceversa!

Me sorprendió cuando leí esto (de la wiki de OpenGL ):

glTranslate, glRotate, glScale

¿Este hardware está acelerado?

No, no hay GPU conocidas que ejecuten esto. El controlador calcula la matriz en la CPU y la carga a la GPU.

Todas las demás operaciones matriciales también se realizan en la CPU: glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.

Esta es la razón por la cual estas funciones se consideran obsoletas en GL 3.0. Deberías tener tu propia biblioteca de matemáticas, construir tu propia matriz, subir tu matriz al sombreador.

Durante mucho, mucho tiempo, pensé que la mayoría de las funciones de OpenGL usan la GPU para hacer cálculos. No estoy seguro de si esto es una idea errónea común, pero después de un tiempo de pensar, esto tiene sentido. Las antiguas funciones de OpenGL (2.xy anteriores) no son realmente adecuadas para las aplicaciones del mundo real, debido a demasiados conmutadores de estado.

Esto me hace darme cuenta de que, posiblemente, muchas funciones de OpenGL no usan la GPU en absoluto.

Entonces, la pregunta es:

¿Qué funciones de OpenGL no usan la GPU?

Creo que conocer la respuesta a la pregunta anterior me ayudaría a convertirme en un mejor programador con OpenGL. Por favor, comparte algunas de tus ideas.

Editar:

Sé que esta pregunta conduce fácilmente al nivel de optimización. Está bien, pero no es la intención de esta pregunta.

Si alguien conoce un conjunto de funciones GL en una determinada implementación popular (como sugirió AshleysBrain, nVidia / ATI, y posiblemente dependiente del sistema operativo) que no usa la GPU, ¡eso es lo que busco!

Las guías de optimización plausibles aparecen más adelante. Vamos a centrarnos en las funciones, para este tema.

Edit2:

Este tema no trata de cómo funcionan las transformaciones de matriz. Hay other topics para eso.


glTranslate, glRotate y glScale cambian la matriz de transformación activa actual. Esto es, por supuesto, una operación de CPU. La vista de modelo y las matrices de proyección solo describen cómo la GPU debe transformar los vértices al emitir un comando de representación.

Entonces, por ejemplo, al llamar a glTranslate, nada se ha traducido aún. Antes de representar la proyección actual y las matrices de vista de modelo se multiplican (MVP = proyección * vista de modelo), esta matriz única se copia a la GPU y luego la GPU realiza las multiplicaciones de matriz * vértice ("T & L") para cada vértice. Entonces, la GPU hace la traducción / escalado / proyección de los vértices.

Además, no debería preocuparse por el rendimiento si no utiliza estas funciones en un bucle interno en algún lugar. glTranslate resultados en tres adiciones. glScale y glRotate son un poco más complejos.

Mi consejo es que deberías aprender un poco más sobre álgebra lineal. Esto es esencial para trabajar con API 3D.


Chico, este es un gran tema.

Primero, comenzaré con lo obvio: como está llamando a la función (cualquier función) de la CPU, tiene que ejecutarse, al menos parcialmente, en la CPU. Entonces la pregunta realmente es, ¿cuánto del trabajo se hace en la CPU y cuánto en la GPU?

En segundo lugar, para que la GPU pueda ejecutar algún comando, la CPU tiene que preparar una descripción de comando para pasar. El conjunto mínimo aquí es un token de comando que describe qué hacer, así como los datos para la operación que se ejecutará. Cómo la CPU activa la GPU para hacer el comando también es algo importante. Como la mayoría de las veces, esto es costoso, la CPU no lo hace a menudo, sino que agrupa los comandos en búferes de comando y simplemente envía un búfer completo para que lo maneje la GPU.

Todo esto para decir que pasar trabajo a la GPU no es un ejercicio libre. Ese costo tiene que ser comparado con solo ejecutar la función en la CPU (no importa de lo que estamos hablando).

Dando un paso atrás, debes preguntarte por qué necesitas una GPU. El hecho es que una implementación de CPU pura hace el trabajo (como menciona AshleysBrain). El poder de la GPU proviene de su diseño para manejar:

  • tareas especializadas (rasterización, mezcla, filtrado de texturas, blitting, ...)
  • cargas de trabajo muy paralelas (DeadMG apunta a eso en su respuesta), cuando una CPU está más diseñada para manejar trabajo de subproceso único.

Y esos son los principios rectores a seguir para decidir qué entra en el chip. Cualquier cosa que pueda beneficiarse de ellos debe ejecutarse en la GPU. Cualquier otra cosa debería estar en la CPU.

Es interesante, por cierto. Algunas funcionalidades del GL (antes de la depreciación, en su mayoría) en realidad no están claramente delineadas. Las listas de visualización son probablemente el mejor ejemplo de dicha función. Cada controlador es libre de enviar todo lo que quiera de la secuencia de la lista de visualización a la GPU (generalmente en forma de búfer de comando) para su posterior ejecución, siempre que se mantenga la semántica de las listas GL (y eso es algo difícil en general). Por lo tanto, algunas implementaciones solo eligen enviar un subconjunto limitado de las llamadas en una lista de visualización a un formato calculado y elegir simplemente reproducir el resto de la secuencia de comandos en la CPU.

La selección es otra en la que no está claro si hay valor para ejecutar en la GPU.

Por último, debo decir que, en general, existe poca correlación entre las llamadas API y la cantidad de trabajo en la CPU o la GPU. Una API de configuración de estado tiende a modificar solo una estructura en algún lugar de los datos del controlador. Su efecto solo es visible cuando se llama un Draw, o algo así.

Gran parte de la API GL funciona así. En ese momento, preguntar si glEnable(GL_BLEND) se ejecuta en la CPU o GPU es bastante insignificante. Lo que importa es si la fusión ocurrirá en la GPU cuando se llame a Draw. Entonces, en ese sentido, la mayoría de los puntos de entrada GL no se aceleran en absoluto.

También podría ampliar un poco la transferencia de datos, pero Danvil lo tocó.

Terminaré con el pequeño "camino s / w". Históricamente, GL tuvo que trabajar para especificar sin importar cuáles eran los casos especiales de hardware. Lo que significaba que si el h / w no manejaba una función GL específica, entonces tenía que emularla o implementarla completamente en el software. Hay numerosos casos de esto, pero uno que golpeó a mucha gente es cuando GLSL comenzó a aparecer.

Como no había una forma práctica de estimar el tamaño del código de un sombreador GLSL, se decidió que el GL debía tomar cualquier longitud de sombreado como válida. La implicación fue bastante clara: implementamos h / w que podría tomar sombreadores de longitud arbitrarios -no realistas en el momento-, o implementamos emulación de shader / w (o, como algunos proveedores eligen, simplemente no cumplen). Por lo tanto, si activó esta condición en un sombreador de fragmentos, era probable que toda su GL terminara ejecutándose en la CPU, incluso cuando tenía una GPU emplazada inactiva, al menos para ese sorteo.


Existen implementaciones de software OpenGL, por lo que es posible que no se ejecuten funciones OpenGL en la GPU. También hay hardware que no admite ciertos estados de procesamiento en el hardware, por lo que si establece un estado determinado, cambie a la representación del software, y nuevamente, nada se ejecutará en la GPU (aunque haya uno allí). Por lo tanto, no creo que haya una distinción clara entre 'funciones aceleradas por GPU' y 'funciones aceleradas que no son GPU'.

Para estar seguro, mantén todo lo más simple posible. La renderización directa con vértices y las funciones básicas como el almacenamiento en memoria Z tienen más probabilidades de ser aceleradas por hardware, por lo que si puedes mantenerte con el mínimo cambio de estado, lo más probable es que mantengas el hardware acelerado. Esta es también la forma de maximizar el rendimiento del renderizado acelerado por hardware: las tarjetas gráficas les gusta quedarse en un estado y simplemente crujir un montón de vértices.


SI lo que estás preguntando es, "¿Puedes escribir automáticamente código acelerado por GPU para utilizarlo con GCC y LLVM?" la respuesta es sí. NVIDIA y Google realizan proyectos de compilación basados ​​en LLVM de código abierto:

NVIDIA CUDA LLVM:

GOOGLE GPUCC:

Si su pregunta es, "¿puedo usar la GPU para acelerar la compilación de código genérico que no es de CUDA?" la respuesta es actualmente no. La GPU es buena en ciertas cosas, como tareas paralelas, mal en otras, como las ramas de las que se tratan los compiladores. La buena noticia es que puede usar una red de PC con CPU para obtener aceleraciones de compilación de 2-10x, dependiendo de cuán optimizado sea su código, y puede obtener la CPU de núcleo múltiple más rápida y la SSD de alta velocidad disponibles para su escritorio para obtener ganancias por menos problemas antes de recurrir a construcciones de red.

Existen herramientas para distribuir tareas del compilador C / C ++ / ObjC a una red de computadoras como Distcc. Se incluyó en versiones anteriores de XCode pero se eliminó, y no hay soporte para usarlo con Swift.

Existe una herramienta comercial similar a Distcc llamada Incredibuild que admite entornos de desarrollo de Visual Studio C / C ++ y Linux:

Hay algunos buenos artículos sobre el uso en el mundo real de Incredibuild vs Distcc y las compensaciones en comparación con el soporte de compilación incremental en el compilador nativo para hacer pequeños cambios como una sola línea en un solo archivo sin recompilar todo lo demás. Puntos a considerar:

  • Puede acelerar una base de código de manera significativa precompilando encabezados, utilizando varias DLL y usando compilaciones incrementales en una sola máquina.
  • Incredibuild es una solución más completa para distribuir automáticamente el trabajo y garantizar el mismo resultado que una compilación en serie, en comparación con hacerlo de forma gratuita con distcc, donde debe trabajar mucho más con los mismos resultados y compatibilidad con cualquier otra cosa que no sea gcc.
  • Para una revisión detallada, vea http://gamesfromwithin.com/how-incredible-is-incredibuild




opengl gpu hardware-acceleration opengl-3