我正在为 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/