2010-04-26 9 views
25

Me sorprendió cuando leí este (desde el OpenGL wiki):¿Qué funciones de OpenGL no son aceleradas por GPU?

glTranslate, glRotate, glScale

se aceleran estos hardware?

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

Todas las otras operaciones de la matriz son realizan en la CPU, así: glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.

Este es el motivo por el cual estas funciones se consideran obsoletas en GL 3.0. Debe tener su propia biblioteca de matemáticas, construir su propia matriz, suba su matriz al sombreador.

Para un muy, muy mucho tiempo pensé que la mayor parte de las funciones de OpenGL utilizan la GPU para hacer el cálculo. 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é llamadas a funciones de OpenGL no utilizan 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 a 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 cierta implementación popular (como sugirió AshleysBrain, nVidia/ATI, y posiblemente dependiente del sistema operativo) que no usa la GPU, ¡eso es lo que estoy buscando!

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

Edit2:

En este tema no se trata de cómo funcionan las transformaciones de matriz. Hay othertopics para eso.

+7

No hay nada de qué sorprenderse. No llama a 'glTranslate' para cada vértice o fragmento, y de todos modos solo es una multiplicación de matriz, por lo que normalmente no se ejecuta ningún rendimiento al ejecutarlo en la CPU. – Thomas

+1

@Thomas: Estás en lo cierto. Pero al principio, es difícil que la gente piense en el canal de renderizado de gráficos, y donde el sombreador de vértices se encuentra con 'glTranslate()'. Después de un tiempo se vuelve más claro, pero al principio pensé "Oh, esto debe ser acelerado por GPU", de ahí la pregunta. –

+0

Pensé que T & L significaba Transformación e iluminación, que es (¿fue?) Acelerada por la tarjeta gráfica. –

Respuesta

35

Chico, es este un gran tema.

En primer lugar, comenzaré con lo obvio: Dado que está llamando a la función (cualquier función) de la CPU, tiene que funcionar 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 debe 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). La potencia de la GPU se debe a su diseño para manejar:

  • tareas especializadas (rasterización, mezcla, filtrado de texturas, blitting, ...)
  • cargas de trabajo
  • en gran medida paralelas (DeadMG está apuntando a que en su respuesta) , cuando una CPU está más diseñada para trabajar con un solo subproceso.

Y esos son los principios rectores a seguir para decidir qué incluye 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 desee 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 de visualización GL (y eso es un poco 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 donde no está claro si la ejecución de la GPU tiene algún valor.

Por último, tengo que decir que, en general, hay 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 punto, 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 de 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 manera 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 ese momento-, o implementar una emulación de sombreado s/w (o, como algunos proveedores eligen, simplemente no cumplen). Entonces, si activó esta condición en un sombreador de fragmentos, era probable que el entero de su GL terminara ejecutándose en la CPU, incluso cuando tenía una GPU emplazada inactiva, al menos para ese sorteo.

+2

Tengo que decir, que * es * un largo post. También tiene mucha historia, muy agradable. Disfruté muchísimo leerlo. Hasta ahora, he llegado a la conclusión de que no es una lista definitiva, pero más de una pauta general y la comprensión de sí? Gracias a todos. Voy a aceptar esta respuesta y reflexionar sobre el próximo imposible. –

7

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 las funciones potencialmente "peligrosas" son, por ejemplo, glReadPixels, porque los datos se pueden copiar de la memoria del host (= CPU) al dispositivo (= GPU) sobre el bus limitado. En esta categoría también se encuentran funciones como glTexImage_D o glBufferData.

Por lo general, 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!

+0

Gracias, Danvil. Has sacado una buena clave candidata para elegir qué funciones consumen tiempo de CPU. Y bus de memoria también. +1. –

2

Hay implementaciones de software OpenGL, por lo que es posible que no OpenGL funcione 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 mayor seguridad, mantenga las cosas lo más simples posible. La renderización directa con vértices y funciones básicas como el almacenamiento en memoria intermedia Z son más probable es que sea acelerado por hardware, por lo que si puede seguir con el cambio mínimo de estado, lo más probable es que acelere el hardware. 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.

+0

@Ashleys, consideré las diferentes implementaciones diferentes de OpenGL, y dónde dibujar esa línea para esta pregunta. Creo que estoy buscando una mayoría de votos, aquí. Gracias por el consejo para mantener las cosas simples! –

+2

Quizás podría formular la pregunta sobre las tarjetas ATI/nVidia/Intel (estremecimiento) u otros fabricantes líderes, ya que supongo que ese es el caso del mundo real donde la aceleración importa. – AshleysBrain

+1

Podría. Pero creo que estas marcas son lo suficientemente populares como para no garantizar tal aclaración, ¿no? –

4

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.

Así, 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 única matriz se copia a la GPU y luego la GPU realiza las multiplicaciones de matriz * vértice ("T & L") para cada vértice. Por lo tanto, la traducción/escalado/proyección de los vértices es realizada por la GPU.

También realmente no debería preocuparse por el rendimiento si no utiliza estas funciones en un bucle interno en alguna parte. 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 el álgebra lineal. Esto es esencial para trabajar con API 3D.

+0

La traducción, la rotación y el escalamiento se pueden realizar mediante operaciones de matriz y el hardware puede hacerlo muy rápidamente. No son parte de la tubería, solo cambian una matriz en la tubería, por lo que tiene sentido mantenerla en la CPU. Pero entonces, ¿POR QUÉ poner estas funciones en la API de OpenGL? Puedo ver la fuente de la confusión. – phkahler

+0

Historia. Creo que esto tiene algo que ver con el modelo de cliente/servidor y la pila de matriz que proporciona el controlador. D3D es más limpio en ese sentido, porque pone estas funciones en D3DX. –

+0

Gracias, Axel, por aclarar dónde se cargan las matrices en la GPU. Soy consciente de cómo funcionan estas matrices y cómo funcionan en términos matemáticos. Mientras editaba el tema, no me preocupa la velocidad en este tema. || Por cierto, ¿sabes cómo "copiar" esta matriz MVP en la GPU para renderizar con OpenGL 3.x? Conozco una forma, vertex shader, pero ¿hay una forma más preferida? || (Mi voto ascendente está limitado, lo hará +1 cuando pueda.) –

7

Normalmente, si una operación es por algo, ocurrirá en la GPU. Un ejemplo es la transformación real: esto se hace una vez por vértice. Por otro lado, si ocurre solo una vez por operación grande, estará en la CPU, como la creación de la matriz de transformación, que solo se realiza una vez por cada vez que cambia el estado del objeto, o una vez por cuadro.

Esa es solo una respuesta general y algunas funcionalidades ocurrirán al revés, además de depender de la implementación. Sin embargo, típicamente, no debería importarle a usted, el programador. Siempre y cuando permita que la GPU tenga mucho tiempo para hacer su trabajo mientras está haciendo simulaciones del juego o lo que sea, o tenga un modelo de subprocesamiento sólido, no debería preocuparse tanto por eso.

@sending data to GPU: Hasta donde yo sé (solo usó Direct3D) todo está hecho en shader, para eso están los shaders.

+0

@DeadMG: Su respuesta fue mi otra opción, lo digo. Conciso y corto. –

Cuestiones relacionadas