Domanda

sto scrivendo gestore per OpenGL consistenza e sto pensando di sicurezza e prestazioni. Quale livello di ottimizzazione dovrebbe rimuovere segnato if?


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(...);
}
È stato utile?

Soluzione

Nessuno.

storia triste, ma C ++ presuppone che se si chiama una funzione, allora questa funzione potrebbe produrre tutti i tipi di effetti collaterali, tra cui la modifica del valore di binded.ID (che la funzione sa in qualche modo a che fare)

ad eccezione di

Se si fare in modo che le funzioni si richiama hanno modo assolutamente legale per conoscere il vostro bindend.ID, sia direttamente (facendo riferimento a esso) o indirettamente (perché qualcun altro prendere un puntatore di esso e lo passò in giro). Ecco un semplice esempio (supponendo che side_effect() situata in un'unità diversa traduzione)

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() può utilizzare e cambiare k legalmente dichiarando come un esterno. Nessuna chiamata di side_effect può essere ottimizzato via.

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;
}

Non è possibile per side_effect per l'accesso k in maniera consentita, in quanto non è possibile statica di accesso in un'altra unità di traduzione. Pertanto il codice può essere ottimizzato per side_effect(); return 0 perché k non cambierà, finché side_effect () non frugare nella memoria. Quale sarebbe un comportamento indefinito, naturalmente.

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;
}

Il compilatore non ha modo di sapere, se snitch() salva il suo argomento in un luogo dove side_effect() può cambiare, quindi, nessuna chiamata a side_effect() può essere eliminato.

È possibile ottenere la stessa situazione, se avete k come variabile locale: Se c'è una possibilità che alcuni sconosciuti k routine di accesso lattina in modo legale, allora il compilatore non può fare ottimizzazioni in base al valore di k <. / p>

PS: Fare k const non aiuta, perché è legale per lanciare un const distanza. const-ness non può essere usato come un suggerimento di ottimizzazione.

Altri suggerimenti

Questo dipenderà dal compilatore e la soluzione migliore è quella di prova -. Compilazione e ispezionare il codice macchina emessa

Nessun livello di ottimizzazione può (giustamente) rimuovere questi test. Essi potrebbero essere rimossi solo se entrambi gli argomenti erano costanti in fase di compilazione, e nessuno di questi sono, o se il compilatore può dimostrare che non cambieranno valore tra le prove.

Dal binded è statico, il compilatore non può sapere che le chiamate alle funzioni GL non alterarlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top