我正在为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(...);
}
答案 0 :(得分:4)
<强>无强>
悲伤的故事,但是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(); return 0
,因为只要side_effect()没有在内存中徘徊,k就不会改变。当然,这将是未定义的行为。
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无效,因为将const转换为合法是合法的。 const-ness不能用作优化提示。
答案 1 :(得分:2)
这取决于编译器,最好的办法是测试 - 编译和检查发出的机器代码。
答案 2 :(得分:2)
没有优化级别可以(正确)删除这些测试。如果两个参数都是编译时常量,并且这两个参数都不是,或者编译器可以证明它们不会在测试之间改变值,那么它们只能被删除。
由于binded
是静态的,编译器无法知道对GL函数的调用不会改变它。