Pregunta

Estoy escribiendo controlador para OpenGL textura y estoy pensando en la seguridad y el rendimiento. ¿Qué nivel de optimización debe quitar marcada si las declaraciones?


struct Texture2D {
    GLuint ID;

    inline Texture2D(): ID(0) {};
    inline explicit Texture2D(GLuint id): ID(id) {};
    ~Texture2D();

    void GenTexture(bool regen = false);
    void DeleteTexture();

    void BindTexture();

    void Parameterf( GLenum pname, GLfloat param );
    void Parameteri( GLenum pname, GLint param );
    void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params );
    void glTexParameteriv( GLenum target, GLenum pname, const GLint *params );

    static Texture2D binded;
};
inline void Texture2D::GenTexture(bool regen) {
    if(ID){
        if(regen)
            DeleteTexture();
        else
            return;
    }

    glGenTextures(1,&ID);
}

inline void Texture2D::DeleteTexture() {
    glDeleteTextures(1,&ID);
    ID = 0;
}

inline void Texture2D::BindTexture() {
    glBindTexture(GL_TEXTURE_2D, ID);
    binded.ID = ID;
}

inline void Texture2D::Parameterf( GLenum pname, GLfloat param ){
    if(binded.ID == ID)                          // THIS
        BindTexture();                           // THIS

    glTexParameterf(GL_TEXTURE_2D,pname,param);
}

inline void Texture2D::Parameteri( GLenum pname, GLint param ){
    if(binded.ID == ID)                          // THIS
        BindTexture();                           // THIS

    glTexParameterf(GL_TEXTURE_2D,pname,param);
}

inline Texture2D::~Texture2D() {
    DeleteTexture();
}

// in this function
void loadTexture(...) {
    Texture2D t;
    t.GenTexture();
    t.BindTexture();
    // if statements in next functions
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
}
¿Fue útil?

Solución

Ninguno.

historia triste, pero C ++ supone que si se llama a una función, esta función podría producir todo tipo de efectos secundarios, incluyendo el cambio del valor de binded.ID (que la función de alguna manera sabe que hacer)

excepto

Si asegurarse de que las funciones se invoca tienen absolutamente ninguna forma legal de saber acerca de su bindend.ID, ya sea directamente (refiriéndose a ella) o indirectamente (porque alguien más tome un puntero de ella y se la pasó alrededor). Aquí está un ejemplo sencillo (suponiendo que side_effect() está en una unidad de traducción diferente)

int side_effect();
int k=1; 

int main()
{
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

side_effect() puede utilizar y el cambio k legalmente declarándolo como externo. Ninguna llamada de side_effect puede ser optimizado de distancia.

int side_effect();
static int k=1; 

int main()
{
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

No es posible que el acceso a side_effect k de una manera permitida, porque no se puede estática de acceso en otra unidad de traducción. Por tanto, el código puede ser optimizado para side_effect(); return 0 porque k no va a cambiar, siempre que side_effect () no hurgar en la memoria. ¿Cuál sería un comportamiento indefinido, por supuesto.

int side_effect();
void snitch(int*);

static int k=1; 

int main()
{
    snitch(&k); // !!!
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

El compilador no tiene forma de saber, si snitch() salva su argumento en un lugar donde side_effect() puede cambiarlo, por lo tanto, no hay ninguna llamada a side_effect() puede ser eliminado.

obtener la misma situación, si tiene k como una variable local: Si existe la posibilidad de que algunos desconocidos k acceso posible que la rutina de una manera legal, entonces el compilador no puede realizar optimizaciones basado en el valor de k <. / p>

PS: no hacer const k no ayuda, ya que es legal para emitir una constante de distancia. const-dad no puede ser utilizado como una receta de optimización.

Otros consejos

Esto dependerá del compilador y su mejor apuesta es a prueba -. Compilación e inspeccionar el código de máquina emitida

Ningún nivel de optimización puede (correctamente) eliminar las pruebas. Sólo podían ser eliminados si ambos argumentos eran constantes en tiempo de compilación, y ninguno de estos son, o si el compilador puede demostrar que no van a cambiar de valor entre las pruebas.

Desde binded es estático, el compilador puede no saber que las llamadas a las funciones GL no alterarán la misma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top