2012-04-26 10 views
5

Escribo un sombreador de fragmentos para WebGL (GLSL ES 1.0) utilizando la última versión de Chrome (y Firefox), y escribí un algoritmo iterativo.Evitar desenrollar bucles en el sombreador de fragmentos

Entonces, en primer lugar, descubrí que la duración del ciclo es bastante restringida (el documento dice que debe ser adivinable en tiempo de compilación, lo que significa que debe ser constante o muy cercano).

Además, tengo que escribir un (for, ya que es el único que debe se aplica con arreglo a la norma) bucle que es potencialmente mucho tiempo, pero que rompe casi todas las veces antes del final.

Ahora, me he dado cuenta de que si configuro un número máximo más alto, la compilación y el enlace del sombreador toman mucho más tiempo. Entonces, a menos que esté equivocado, el compilador desenrolla el lazo.

No estoy seguro de si se puede hacer algo, pero he intentado algunas cosas y el compilador también parece tener funciones en línea, incluso cuando se le llaman en bucles.

No creo que sea normal que un sombreador tarde un minuto en compilarse para un centenar de iteraciones de un bucle. ¿O estoy haciendo lo incorrecto? ¿Hay cientos de iteraciones en un fragmentador de fragmentos demasiado para una GPU? Porque parece funcionar bien una vez que se ha compilado.

+0

WebGL generalmente solo entrega el sombreador al compilador en su biblioteca OpenGL, entonces, ¿qué hace y cuánto tiempo lleva depende de su tarjeta de video y controlador ... –

Respuesta

4

Esta es una de las desafortunadas realidades de GLSL. Sería genial si pudiéramos hacer una compilación sin conexión y enviar un bytecode, o si tuviéramos la capacidad de especificar indicadores en tiempo de compilación, etc., pero así no es exactamente como funciona la especificación. Usted está completamente a merced del fabricante del controlador. Si NVIDIA/ATI piensa que el desenrollado de bucles es bueno para usted, su bucle se desenrollará.

Sin embargo, me pregunto qué es lo que estás haciendo que requiere tanto bucle. Los sombreadores no son realmente el lugar correcto para realizar cálculos súper complejos de bucles o bifurcaciones. Sin duda tendrá un éxito de rendimiento para él. Si no está preocupado por el rendimiento en tiempo real, entonces tal vez un gran error de compilación al inicio de su programa no sea tan malo. Si le preocupa la velocidad de renderizado de su aplicación, es probable que necesite volver a evaluar la complejidad de los sombreadores.

2

Menciona que el sombreador tarda más de un minuto en compilar un bucle con un máximo de aproximadamente 100 iteraciones, y esto me hace pensar que su problema podría estar relacionado con ANGLE.

ANGLE es una pieza de software integrada en navegadores compatibles con WebGL en el sistema operativo Windows, que toma su sombreador GLSL y lo traduce en tiempo de ejecución en un sombreador Direct3D HLSL. La idea es que la mayoría de las máquinas con Windows tienen controladores Direct3D más nuevos en comparación con sus controladores OpenGL, por lo que el comportamiento predeterminado es convertir todo en D3D. En mi experiencia, esto puede ser lento, especialmente con bucles largos como usted describe, aunque es necesario para muchos usuarios de Windows, especialmente aquellos con gráficos basados ​​en Intel.

Si está ejecutando Windows y tiene controladores OpenGL de buena calidad, como los relativamente nuevos de nVidia o AMD, puede intentar deshabilitar ANGLE para ver si soluciona su problema. En Google Chrome esto se hace editando su icono de Chrome para agregar --use-gl=desktop como un parámetro de línea de comandos (en el campo 'objetivo' del icono) y reiniciar el navegador. Para Firefox, puede visitar about:config y escribir webgl en el cuadro de búsqueda, y buscar webgl.prefer-native-gl y establecerlo en verdadero.

Pruebe su sombreador nuevamente con ANGLE deshabilitado, y los tiempos de compilación pueden mejorarse. Tenga en cuenta que esto es solo un problema de Windows, por lo que editar estos ajustes en otras plataformas no tiene ningún efecto, pero creo que todas las demás plataformas usan directamente OpenGL nativo.

0

Lamentablemente AMD podría no es compatible con esto, pero creo que NVidia tiene una buena directiva pragma de desenrollar. Para las personas que están teniendo el problema opuesto, lo invocaría como "opción #pragmaNV (desenrollar todo)" en GLSL, pero creo que lo siguiente evitará que se desenrolle. Cito DenisR's 2008 post on the NVidia forums:

De forma predeterminada, el compilador desenrolla pequeños bucles con un conteo conocido de viajes. Sin embargo, la directiva #pragma Unroll se puede usar para controlar el desenrollamiento de cualquier ciclo dado. Debe colocarse inmediatamente antes del bucle y solo se aplica a ese bucle. Opcionalmente, sigue un número que especifica cuántas veces se debe desenrollar el bucle.

Por ejemplo, en este ejemplo de código:

el bucle se desenrolla 5 veces. Depende del programador asegurarse de que el desenrollamiento no afecte la corrección del programa (que, en el ejemplo anterior, si n es menor que 5).

#pragma unroll 1 

evitará que el compilador siempre desenrollar un bucle.

Si no se especifica un número después del desenrollado #pragma, el ciclo se desenrolla por completo si su recuento de disparos es constante; de ​​lo contrario, no se desenrollará.

Así que me imagino que

#pragma optionNV (unroll 1) 

podría funcionar en GLSL (y WebGL?). (Por ejemplo, StackOverflow question selective-nvidia-pragma-optionnvunroll-all parece dar a entender que esto puede funcionar en GLSL, al menos en algunas plataformas.)

Parece que hay una implicación de que en los últimos años, AMD podría apoyar un pragma desenrollado (quizás no en GLSL sin embargo), pero no estoy familiarizado y no lo he probado: unroll loops in an AMD OpenCL kernel

(Si se utiliza GLSL a través de WebGL en Chrome/Firefox, o incluso otros escenarios, tenga en cuenta que la compilación GLSL puede ser canalizado a través ANGLE, lo que podría dar a un backend HLSL en Windows, tal vez. Tengo una comprensión muy limitada de esto y no deseo difundir información, así que definitivamente no cite eso, simplemente sentí que era necesario compartir la información que había reunido sobre este problema, por lo que ahora, y gustosamente editaremos esto respuesta (o las personas deben sentirse libres de editar esta respuesta) a medida que haya más información confirmada disponible.)

Cuestiones relacionadas