Érase una vez, cuando > era más rápido que

7 minutos de lectura

avatar de usuario
Armen Tsirunyan

Estoy leyendo un impresionante 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 (cuál es superior y cuál no) también puede ser personalizado 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 lejano del espectador.

Anteriormente, se dijo que el valor Z del espacio de la ventana de 0 es el más cercano y 1 es el más lejano. Sin embargo, si nuestros valores Z del espacio de recorte fueran negados, 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. Así que en realidad es solo una convención. De hecho, cambiar el signo de Z y la prueba de profundidad alguna vez 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 un < comparación con un > comparación. Entonces, si entiendo correctamente y el autor no está mintiendo o inventando cosas, entonces cambiando < a > solía ser una optimización vital para muchos juegos.

¿El autor está inventando cosas, estoy malinterpretando algo, o es realmente el caso que una vez < era más lento (vitalmentecomo dice el autor) que >?

¡Gracias por aclarar este asunto tan curioso!

Descargo de responsabilidad: Soy plenamente consciente de que la complejidad del algoritmo es la fuente principal de optimizaciones. Además, sospecho que hoy en día definitivamente no haría ninguna diferencia y no estoy pidiendo esto para optimizar nada. Soy extremadamente, dolorosamente, tal vez prohibitivamente curioso.

  • (a < b) es idéntico a (b > a) por lo que no hay absolutamente ninguna necesidad de implementar ambas operaciones de comparación en el hardware. La diferencia en el rendimiento es el resultado de lo que sucede como resultado de la operación de comparación. Este es un camino largo y sinuoso para explicar todos los efectos secundarios, pero aquí hay algunos consejos. Los juegos solían llenar el búfer de profundidad para evitar un procesamiento de fragmentos más costoso para los fragmentos que fallaron la prueba de profundidad. Quake solía dividir el rango de profundidad en dos mitades para evitar borrar el búfer de cuadros porque el juego siempre llenaba cada píxel en la pantalla y así sucesivamente.

    – t0rakka

    27 de diciembre de 2017 a las 14:24


  • Aquí está el versión archivada del tutorial de OpenGL al que se hace referencia. Sin embargo, parece que no puedo encontrar el fragmento citado, tal vez lo eliminaron.

    – Fons

    8 de julio de 2018 a las 13:03


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 < a una > comparación. Entonces, si entiendo correctamente y el autor no está mintiendo o inventando cosas, entonces cambiar < a > solía ser una optimización vital para muchos juegos.

No lo expliqué particularmente bien, porque no era importante. Simplemente sentí que era un poco interesante de trivia para agregar. No tenía la intención de repasar 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 optimización antigua específica en la que un cuadro usaría GL_LESS con una gama de [0, 0.5]. Siguiente cuadro, renderizas con GL_GREATER con una gama de [1.0, 0.5]. Avanzas y retrocedes, 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 tenía que borrar el búfer de profundidad, que alguna vez fue una operación bastante lenta. Dado que la limpieza profunda 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.

  • La razón por la que borrar el búfer de profundidad es más rápido en estos días tiene dos razones, ambas basadas en el hecho de que la GPU usa un búfer de profundidad jerárquico. Por lo tanto, solo tiene que borrar los estados del mosaico para borrar (lo cual es rápido), sin embargo, cambiar el signo de comparación de profundidad significa que todo el búfer HiZ debe vaciarse porque solo almacena un valor mínimo o máximo según el signo de comparación.

    –Jasper Bekkers

    29 de junio de 2012 a las 19:41

  • @NicolBolas: comentario de PerTZHX, el enlace a su tutorial en mi pregunta se ha interrumpido. ¿Podría decirnos a dónde se han movido los tutoriales y, opcionalmente, editar la pregunta, por favor?

    – Armen Tsirunyan

    24 de marzo de 2015 a las 12:57

  • Los tutoriales están disponibles en el archivo web. Si @NicolBolas lo permite, sería útil para la comunidad si pudiéramos trasladarlos a un lugar más accesible. Tal vez GitHub o algo así. web.archive.org/web/20150215073105/http://arcsíntesis.org/…

    – ApoorvaJ

    27 de junio de 2015 a las 13:21

La respuesta es casi seguro que para cualquier encarnación de chip+controlador que se haya utilizado, la Z jerárquica solo funcionó 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 búfer Z se realiza en hardware de función fija y se canaliza; no hay especulación y, por lo tanto, no hay predicción de ramificación.

avatar de usuario
Josué

Tiene que ver con los bits de bandera en un ensamblaje altamente afinado.

x86 tiene instrucciones jl y jg, pero la mayoría de los procesadores RISC solo tienen jl y jz (no jg).

  • Si esa es la respuesta, plantea nuevas preguntas. ¿La “rama tomada” era más lenta que la “rama ignorada” en los primeros procesadores RISC? Ciertamente no es así ahora de ninguna manera medible hasta donde yo sé. se suponía que debías escribir for bucles con una rama incondicional hacia atrás y una rama condicional, que rara vez se toma hacia adelante para salir del bucle, entonces? Suena incómodo.

    – Pascal Cuoq

    7 sep 2011 a las 19:43


  • -1: Esta pregunta tiene nada que ver con las CPU. GL_LESS y GL_GREATER son operaciones de comparación de profundidad, que se ejecutan en GPU.

    – Nicolás Bolas

    7 sep 2011 a las 20:29

  • Es curioso la cantidad de representantes que puede obtener por una respuesta que es correcta para el título pero que tiene muy poco que ver con la pregunta real.

    – Josué

    8 de septiembre de 2011 a las 1:12

  • +1 No, esta respuesta es correcta al menos en parte de la pregunta. La pregunta es: “¿El autor está inventando cosas, estoy malinterpretando algo, o es cierto que una vez < fue más lento (vitalmente, como dice el autor) que >?”. Hay tres opciones dadas. Esta respuesta responde a la posibilidad de la opción 3. En ninguna parte del artículo se da la tecnología de la CPU/GPU, ni que debe ser una GPU (los primeros juegos 3D en la CPU). Ok… no creo que haya muchos juegos 3d en RISC 🙂

    – xánatos

    14 de septiembre de 2011 a las 9:57

  • (y la etiqueta GPU se agregó a las 20:34. La primera revisión solo tenía la etiqueta CPU. Esta respuesta se escribió a las 18:44)

    – xánatos

    14 de septiembre de 2011 a las 10:12

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad