1 puntos por GN⁺ 2025-02-10 | 1 comentarios | Compartir por WhatsApp

Introducción

  • Este artículo busca corregir ideas erróneas relacionadas con las bifurcaciones en GPU.
  • Algunos sitios web educativos están difundiendo información incorrecta, y se busca corregirla.

Problema

  • Se presenta un ejemplo de código que usa el operador ternario para implementar ejecución condicional en código de GPU.
  • Algunas personas proponen una “optimización” que lo reemplaza por operaciones aritméticas, pero eso parte de un malentendido.
  • El operador ternario realiza un movimiento condicional, y esto se implementa con operaciones de bits simples.
  • Las bifurcaciones reales sí ocurren en código de GPU, pero no se usan para pequeños movimientos de registros.

Problemas de la optimización errónea

  • La optimización propuesta en realidad se ejecuta más lento que el código original.
  • La función step() está implementada con un operador ternario, por lo que realiza multiplicaciones y sumas innecesarias adicionales.
  • En el código original, el valor se mueve directamente de forma condicional.

Análisis de código máquina

  • A través del código máquina de los compiladores de AMD y Microsoft, puede confirmarse que la GPU no realiza bifurcaciones.
  • Se usan operaciones de comparación y máscaras de bits para realizar el movimiento condicional.

Conclusión

  • La propuesta de optimización usando la función step() es información incorrecta y debe corregirse.

  • Esta desinformación se ha difundido durante más de 20 años, y es necesario corregirla.

  • Inigo Quilez - estudiando gráficos por computadora desde 1994.

1 comentarios

 
GN⁺ 2025-02-10
Opinión de Hacker News
  • Estoy convencido de que la conclusión del artículo fuente es correcta, pero el argumento sería más sólido si se mostrara la generación de código de ambas versiones, no solo de la mejor

    • Muestra el código máquina generado para demostrar que la versión "optimizada" en realidad se ejecuta mucho más lento que la versión original, pero no prueba que la versión mala sea peor
  • Ojalá hubiera una buena forma de saber en qué casos if realmente fuerza una bifurcación

    • La razón por la que la gente usa mix/lerp, aunque pueda haber una pequeña sobrecarga, es porque le teme a generar una bifurcación
    • Está bien que v = x > y ? a : b; funcione de verdad, pero preocupa que if sea una construcción que a veces genera bifurcación y a veces no
  • Este artículo también está relacionado: corrige malos consejos sobre cómo escribir bifurcaciones en GPU

    • Antes sí funcionaban las optimizaciones para evitar bifurcaciones, pero ahora ya no debería hacerse
    • Como los procesadores y compiladores cambian, conviene ofrecer varias variantes y elegir en tiempo de ejecución la más rápida
  • Me pregunto por qué el compilador no puede reconocer que la versión "optimizada" es equivalente

    • Debería poder entender step() y optimizar por separado los casos step()=0.0 y step()==1.0
  • Me he topado con este problema. Claude/ChatGPT también lo sugieren como optimización, pero termina degradando el rendimiento

    • Gracias a Inigo
  • Me pregunto cómo saber si una función de OpenGL está siendo emulada en lugar de invocar una capacidad nativa de la GPU

  • Al escribir código, hace falta experiencia para tener la seguridad de que no habrá una bifurcación condicional

    • Es difícil saber cuántas operaciones después de la condición provocan una bifurcación y qué operaciones puede omitir el compilador
    • Me pregunto si habría que usar una suite de pruebas de rendimiento para detectar degradaciones accidentales
  • Explica cómo funciona la variante de la función mix para vectores