具有相同 if 语句的 C++ 内联方法

标签 c++ compiler-optimization inline-method

我正在为 OpenGL 纹理编写处理程序,我正在考虑安全性和性能。哪个优化级别应该删除标记的 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(...);
}

最佳答案

无。

悲伤的故事,但 C++ 假设如果您调用一个函数,那么该函数可能会产生各种副作用,包括更改 binded.ID 的值(该函数以某种方式知道该怎么做)

除了

如果您确定您调用的函数绝对没有合法的方式来了解您的 bindend.ID,无论是直接(通过引用它)还是间接(因为其他人获取它的指针)并传递它)。这是一个简单的例子(假设 side_effect() 在不同的翻译单元中)

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() 可以通过将其声明为外部来合法地使用和更改k。无法优化掉 side_effect 的调用。

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

side_effect 不可能以允许的方式访问 k,因为您无法访问另一个翻译单元中的静态信息。因此代码可以优化为 side_effect();返回 0 因为 k 不会改变,只要 side_effect() 不在内存中四处寻找。这当然是未定义的行为。

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

编译器无法知道 snitch() 是否将其参数保存在 side_effect() 可以更改的位置,因此不会调用 side_effect() 可以消除。

如果您将 k 作为局部变量,您会遇到同样的情况:如果某个未知例程有可能以合法方式访问 k,那么编译器不能根据k的值进行优化。

PS: 使 k 成为常量没有帮助,因为丢弃常量是合法的。 const-ness 不能用作优化提示。

关于具有相同 if 语句的 C++ 内联方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3406395/

相关文章:

c++ - C++中的拆分函数

c++ - 实现功能到QT按钮

c++ - 尽管设置了 EOF 标志,为什么 std::ws 会阻塞?

C++双链表反向打印

c++ - pIter != cont.end() 在 for 循环中的性能

c++ - 模板替换在调试构建中失败,但在优化构建中工作?

c++ - float 编译时计算没有发生?

c++ - 如何避免使用内联函数重复代码?

c++ - 现代 C++ 中的内联方法和代码可读性