optimization - ¿La velocidad de cos() y sin() funcionan en los sombreadores GLSL?
opengl shader (6)
Por ejemplo, en mi aplicación será muy común que el argumento sea 0. Así que algo como esto tiene sentido:
No.
Tu compilador hará una de dos cosas.
- Se emitirá una rama condicional real. En el mejor de los casos, si 0 es un valor que es coherente a nivel local (de modo que grupos de sombreadores a menudo lleguen a 0 o no a cero), entonces es posible que obtenga un mejor rendimiento.
- Evaluará ambos lados de la condición y solo almacenará el resultado para el correcto de ellos. En cuyo caso, no has ganado nada.
En general, no es una buena idea usar la lógica condicional para bailar en presentaciones pequeñas como esta. Debe ser realmente grande para que valga la pena, como un discard
o algo así.
Además, tenga en cuenta que la equivalencia de punto flotante no es probable que funcione. No, a menos que realmente pase un atributo uniforme o de vértice que contenga exactamente 0.0 al sombreado. Incluso la interpolación entre 0 y no cero probablemente nunca producirá exactamente 0 para ningún fragmento.
Me interesa la información sobre la velocidad de sin()
y cos()
en Open GL Shader Language .
El documento de especificación GLSL indica que:
Las funciones integradas básicamente se dividen en tres categorías:
- ...
- ...
- Representan una operación que es probable que el hardware de gráficos se acelere en algún momento. Las funciones de trigonometría caen en esta categoría.
EDITAR:
Como se ha señalado, contar ciclos de reloj de operaciones individuales como sin()
y cos()
realmente no cuenta toda la historia del rendimiento.
Entonces, para aclarar mi pregunta, lo que realmente me interesa es si vale la pena optimizar las llamadas sin()
y cos()
para casos comunes.
Por ejemplo, en mi aplicación será muy común que el argumento sea 0
. Así que algo como esto tiene sentido:
float sina, cosa;
if ( rotation == 0 )
{
sina = 0;
cosa = 1;
}
else
{
sina = sin( rotation );
cosa = cos( rotation );
}
¿O el compilador GLSL
o las implementaciones sin()
y cos()
se ocuparán de optimizaciones como esa para mí?
El compilador evalúa ambas ramas, lo que hace que las condiciones sean bastante caras. Si usa tanto el pecado como el cos en su sombreado, puede calcular solo el pecado (a) y el cos (a) = sqrt (1.0 - sin (a)) ya que sin (x) * sin (x) + cos (x) * cos (x) es siempre 1.0
Esta es una buena pregunta. Yo también me pregunté esto.
Los enlaces de Google dicen que cos
y sin
son ciclos únicos en las tarjetas comunes desde 2005 o así.
No estoy seguro de si esto responde a su pregunta, pero es muy difícil decirle cuántos relojes / ranuras toma una instrucción, ya que depende mucho de la GPU. Normalmente es un ciclo único. Pero incluso si no es así, el compilador puede reorganizar el orden de ejecución de la instrucción para ocultar el costo real. Es ciertamente más lento usar búsquedas de texturas para sin / cos, ya que es para ejecutar las instrucciones.
Tendrías que probar esto tú mismo, pero estoy bastante seguro de que bifurcar en un shader es mucho más costoso que un cálculo de sin
o cos
. Los compiladores GLSL son bastante buenos para optimizar los sombreadores, preocuparse por esto es una optimización prematura. Si luego descubre que, a través de todo su programa, sus sombreadores son el cuello de botella, entonces puede preocuparse por optimizar esto.
Si desea echar un vistazo a un código de ensamblaje de su sombreado para una plataforma específica, recomendaría AMD GPU ShaderAnalyzer .
vea cuántos pecados puede obtener en un shader en una fila, en comparación con math.abs, frac, ect ... creo que un gtx 470 puede manejar 200 funciones sin por fragmento, no hay problemas, el marco será un 10 por ciento más lento que un sombreador vacío. Es muy rápido, puede enviar resultados. Será un buen indicador de la eficiencia computacional.