结构数组或数组结构性能

时间:2012-03-10 20:40:49

标签: opengl

我正在使用AMD Radeon HD 6630M的MacMini '11。我正在使用数组结构绘制一个网格,一切都很好:60 fps(使用CVDisplayLink)。我使用具有内置属性的着色器。生活很好。我正在转向使用一组结构(交错),因为我知道这是“现代”GPU的首选。属性在着色器中定义。网格绘制精美。但是当我这样做时,帧速率下降了大约33%(到40 fps)。这些电话有多个副本。使用Instruments:Time Profiler,我得到以下比较:

Using structure of arrays (60 fps)
Running Time    Self    Symbol Name
3.0ms    0.0%   3.0 0x21b76c4           ATIRadeonX3000GLDriver
2.0ms    0.0%   0.0  gldUpdateDispatch  ATIRadeonX3000GLDriver
2.0ms    0.0%   0.0    gleDoDrawDispatchCore        GLEngine
2.0ms    0.0%   0.0     glDrawElements_ACC_Exec GLEngine
2.0ms    0.0%   0.0      glDrawElements     libGL.dylib
2.0ms    0.0%   0.0       -[Mesh draw]      me

Using array of structures (40 fps)
Running Time    Self        Symbol Name
393.0ms    7.4% 393.0   0x86f6695               ?
393.0ms    7.4% 0.0  gleDrawArraysOrElements_ExecCore   GLEngine
393.0ms    7.4% 0.0    glDrawElements_IMM_Exec      GLEngine
393.0ms    7.4% 0.0     glDrawElements          libGL.dylib
393.0ms    7.4% 0.0     -[Mesh draw]            me

看起来libGL正在决定向不同的方向发展,结构数组似乎没有被调用X3000驱动程序。它是在Apple软件模拟器中执行的吗?我应该继续使用数组结构吗?有没有人见过这样的东西?


属性代码来自Apple示例,在我的应用程序中使用(至少10个其他区域),在这些区域没有性能影响。这是来自慢速版本。正如我所提到的,我在快速版本中使用内置属性,因为数据不是交错的。渲染点亮,只是很慢。

我希望这就是你要找的东西:

//  Step 5 - Bind each of the vertex shader's attributes to the programs
[self.meshShader addAttribute:@"inPosition"];
[self.meshShader addAttribute:@"inNormal"];
[self.meshShader addAttribute:@"inTexCoord"];

//  Step 6 - Link the program
if([[self meshShader] linkShader] == 0){
    self.posAttribute = [meshShader attributeIndex:@"inPosition"];
    self.normAttribute = [meshShader attributeIndex:@"inNormal"];   
    self.texCoordAttribute = [meshShader attributeIndex:@"inTexCoord"]; 

...


- (void) addAttribute:(NSString *)attributeName
{
    if ([attributes containsObject:attributeName] == NO){
        [attributes addObject:attributeName];
        glBindAttribLocation(program, [attributes indexOfObject:attributeName],     
        [attributeName UTF8String]);
    }
}

更新 经过进一步调查: 1)我正在使用dhpoWare的modelObj加载器(已修改),因为它使用了交错的结构数组,它的性能就像我的结构数组一样 - 只是没有点击。我可能会错误地解释乐器。 modelObj代码确实调用glDrawElements_IMM_Exec,它也以环形方式调用gleDoDrawDispatchCore。我不确定它是否只是在glDrawElements_IMM_Exec上累积一堆调用,然后通过gleDoDrawDispatchCore将它们爆破。不知道。 2)我认为Instruments有问题,因为它显示GLEngine调用我未使用的内部3ds对象方法之一,它没有外部钩子。我通过在那里设置Xcode断点进行了双重检查,它从未跳过。我不再做3DS了。

我想我会继续环顾四周,也许会偶然发现答案。如果有人愿意就一系列结构是否可行而给我一个意见,我们将不胜感激。

解: 我在前端添加了一个VBO,一切都很顺利。原始代码来自OpenGL ES 2.0指南,添加VBO修复了我的问题。帧速率为60,1 ms驱动程序调用。这是代码:

glGenVertexArrays(1, &vaoName);
glBindVertexArray(vaoName);

//  new - create VBO
glGenBuffers(1, &vboName);
glBindBuffer(GL_ARRAY_BUFFER, vboName);

//  Allocate and load position data into the VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertexAttribs) * self.numVertices,                                             
                   vertexAttribData, GL_STATIC_DRAW);
//  end of new

NSUInteger  vtxStride = sizeof(struct vertexAttribs);
//GLfloat   *vtxBuf = (GLfloat *)vertexAttribData;    // no longer use this
GLfloat *vtxBuf = (GLfloat *)NULL;                // use this instead

glEnableVertexAttribArray(self.posAttribute);
glVertexAttribPointer(self.posAttribute, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
                        vtxStride, vtxBuf);
vtxBuf += VERTEX_POS_SIZE;

glEnableVertexAttribArray(self.normAttribute);
glVertexAttribPointer(self.normAttribute, VERTEX_NORM_SIZE, GL_FLOAT, GL_FALSE,
                        vtxStride, vtxBuf);
vtxBuf += VERTEX_NORM_SIZE;

glEnableVertexAttribArray(self.texCoordAttribute);
glVertexAttribPointer(self.texCoordAttribute, VERTEX_TEX_SIZE, GL_FLOAT, GL_FALSE,
                        vtxStride, vtxBuf);
...

1 个答案:

答案 0 :(得分:0)

用于在内存中实现单位步幅访问的数组结构是经验法则。它不仅适用于GPU,也适用于CPUS和Intel Xeon Phi等协处理器。

在您的情况下,我不相信这部分代码会被发送到GPU,而是性能损失是由于非单位步进内存访问(CPU到/来自内存)。

相关问题