Estoy leyendo un increíble tutorial de OpenGL . Es realmente genial, confía en mí. El tema en el que estoy actualmente es Z-buffer. Además de explicar de qué se trata, el autor menciona que podemos realizar pruebas de profundidad personalizadas, como GL_LESS, GL_ALWAYS, etc. También explica que el significado real de los valores de profundidad (que es superior y que no lo es) también puede ser Personalizado. Lo entiendo hasta ahora. Y luego el autor dice algo increíble:
El rango zNear puede ser mayor que el rango zFar; si es así, entonces los valores del espacio de la ventana se invertirán, en términos de lo que constituye lo más cercano o lo más alejado del espectador.
Anteriormente, se decía que el valor Z del espacio de ventana de 0 es el más cercano y 1 es el más alejado. Sin embargo, si se negaran nuestros valores Z del espacio de clip, la profundidad de 1 sería la más cercana a la vista y la profundidad de 0 sería la más lejana. Sin embargo, si cambiamos la dirección de la prueba de profundidad (GL_LESS a GL_GREATER, etc.), obtenemos exactamente el mismo resultado. Entonces, en realidad es solo una convención. De hecho, voltear el signo de Z y la prueba de profundidad fue una optimización de rendimiento vital para muchos juegos.
Si entiendo correctamente, en cuanto al rendimiento, cambiar el signo de Z y la prueba de profundidad no es más que cambiar una <
comparación por otra >
. Entonces, si entiendo correctamente y el autor no está mintiendo o inventando cosas, cambiar <
a >
solía ser una optimización vital para muchos juegos.
¿El autor está inventando cosas, estoy malentendiendo algo o es el caso que alguna vez <
fue más lento ( vitalmente , como dice el autor) que >
?
¡Gracias por aclarar este asunto bastante curioso!
Descargo de responsabilidad: soy plenamente consciente de que la complejidad del algoritmo es la fuente principal para las optimizaciones. Además, sospecho que hoy en día definitivamente no haría ninguna diferencia y no estoy pidiendo que esto optimice nada. Soy extremadamente, dolorosamente, tal vez prohibitivamente curioso.
Respuestas:
No expliqué eso particularmente bien, porque no era importante. Simplemente sentí que era un poco interesante de trivia agregar. No tenía la intención de revisar el algoritmo específicamente.
Sin embargo, el contexto es clave. Nunca dije que una comparación <fuera más rápida que una> comparación. Recuerde: estamos hablando de pruebas de profundidad de hardware de gráficos, no de su CPU. No
operator<
.A lo que me refería era a una vieja optimización específica en la que usarías un marco
GL_LESS
con un rango de [0, 0.5]. En el siguiente cuadro, se renderiza conGL_GREATER
un rango de [1.0, 0.5]. Usted va y viene, literalmente "volteando el signo de Z y la prueba de profundidad" en cada cuadro.Esto pierde un poco de precisión de profundidad, pero no tuvo que borrar el búfer de profundidad, que alguna vez fue una operación bastante lenta. Dado que la limpieza en profundidad no solo es gratuita en estos días, sino que en realidad es más rápida que esta técnica, la gente ya no lo hace.
fuente
La respuesta es casi seguro que para cualquier encarnación de chip + driver utilizado, el Z jerárquico solo funcionaba en una dirección: este era un problema bastante común en el pasado. El ensamblaje / ramificación de bajo nivel no tiene nada que ver con esto: el almacenamiento en búfer Z se realiza en hardware de función fija y está canalizado, no hay especulación y, por lo tanto, no hay predicción de ramificación.
fuente
Una optimización como esta afectará el rendimiento en muchas soluciones gráficas integradas porque hará que la resolución de framebuffer sea menos eficiente. Borrar un búfer es una señal clara para el conductor de que no necesita almacenar y restaurar el búfer al binning.
Poca información de fondo: un rasterizador de mosaico / agrupación procesa la pantalla en una cantidad de mosaicos muy pequeños que caben en la memoria del chip. Esto reduce las escrituras y las lecturas en la memoria externa, lo que reduce el tráfico en el bus de memoria. Cuando se completa un marco (se llama a swap, o los FIFO se vacían porque están llenos, los enlaces de framebuffer cambian, etc.) se debe resolver el framebuffer; Esto significa que cada contenedor se procesa a su vez.
El controlador debe asumir que los contenidos anteriores deben conservarse. La preservación significa que el contenedor debe escribirse en la memoria externa y luego restaurarse desde la memoria externa cuando el contenedor se procesa nuevamente. La operación clear le dice al conductor que el contenido del bin está bien definido: el color clear. Esta es una situación que es trivial para optimizar. También hay extensiones para "descartar" el contenido del búfer.
fuente
Tiene que ver con bits de bandera en un ensamblaje altamente sintonizado.
x86 tiene instrucciones jl y jg, pero la mayoría de los procesadores RISC solo tienen jl y jz (no jg).
fuente
for
bucles con una rama incondicional hacia atrás y una rama condicional, rara vez llevada hacia adelante para salir del bucle entonces? Suena raro