C看似平凡的优化没有完成

时间:2017-06-11 21:25:27

标签: c opengl-es-2.0 compiler-optimization llvm-clang

我正在编写的程序包含10个全局函数指针。然后我决定将它们放在一个结构中,看看是否会改变调用两个函数后生成的机器代码。我惊讶地发现利用结构的代码版本包含的两个移动指令比没有结构的代码版本(反汇编的所有其他行都相同)。这是某种奇怪的优化,还是编译器不知道如何消除结构成员调用的开销?我正在使用Clang 3.8作为我的编译器并正在编译x86。

版本与结构:

#include GLES2/gl2.h

struct GLES2FunctionPointers {
    const PFNGLCLEARCOLORPROC glClearColor;
    const PFNGLCREATEPROGRAMPROC glCreateProgram;
};

struct GLES2FunctionPointers GLES2 = {
     .glCreateProgram = 
(PFNGLCREATEPROGRAMPROC)eglGetProcAddress("glCreateProgram"),
    .glCreateShader = 
(PFNGLCREATESHADERPROC)eglGetProcAddress("glCreateProgram"),
};

GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type) {
    return GLES2.glCreateShader(type);
}

GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const 
GLchar *const*string, const GLint *length) {
    GLES2.glShaderSource(shader, count, string, length);
}

没有结构的版本:

const PFNGLCREATESHADERPROC glCreateShaderPointer = (PFNGLCREATESHADERPROC)eglGetProcAddress("glCreateShader");

GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type) {
    return glCreateShaderPointer(type);
}

const PFNGLSHADERSOURCEPROC glShaderSourcePointer = 
(PFNGLSHADERSOURCEPROC)eglGetProcAddress("glCreateProgram");

GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, 
const GLchar *const*string, const GLint *length) {
    glShaderSourcePointer(shader, count, string, length);
}

这是被反汇编的功能:

int prepareShader(GLuint shaderType, const char * shaderCode) {
    GLuint shader = glCreateShader(shaderType);
    int len = strlen(shaderCode);
    glShaderSource(shader, 1, &shaderCode, &len);
    return shader;
}

这是main中的函数调用:

int vertexShader = prepareShader(GL_VERTEX_SHADER, VERTEX_SHADER);
//VERTEX_SHADER is a string in my code

1 个答案:

答案 0 :(得分:1)

结构本身没有开销。 const结构应该针对直接调用进行优化:

https://godbolt.org/g/gBNnp3

如果结构不是常量,则需要首先加载指针值。如果需要填充,则符号的目标代码输出也可能略有不同(如果我尝试使用10个函数,call1最后得到xchg %ax %ax == nop