Opengl es OpenGL ES 2.0步幅性能

Opengl es OpenGL ES 2.0步幅性能,opengl-es,Opengl Es,结构(包含顶点数据)的大小是否会影响中的性能 例如: struct VertexData1 { float x, y, z; } struct VertexData1 { float x, y, z; float variable1, variable2; //any amount of variables } 现在,以下各项之间是否存在性能差异: struct VertexData1 d1; glVertexAttribPointer(index, 3, GL

结构(包含顶点数据)的大小是否会影响中的性能

例如:

struct VertexData1 {
     float x, y, z;
}

struct VertexData1 {
     float x, y, z;
     float variable1, variable2; //any amount of variables
}
现在,以下各项之间是否存在性能差异:

struct VertexData1 d1;
glVertexAttribPointer(index, 3, GL_FLOAT, GL_FALSE, sizeof(struct VertexData1), &d1.x);
vs


是的,因为它会影响后续引用的整体局部性(即,它们的局部性会降低),因此会增加缓存未命中的数量,尤其是当顶点数量增加时

在您的情况下,您没有将阵列存储在GPU上,但如果您对性能感兴趣,您应该这样做。OpenGL无法自动缓存这些内容,因为C中没有簿记功能,它无法判断自上次调用
glvertexattributepointer
以来数组中是否有任何内容发生了更改

一旦你使用GPU,为自己安排好缓存就变得更加重要:GPU是高度并行的,但内存不是。因此,缓存未命中都会退回到共享资源上,因此多个同时发生的未命中会加剧性能问题


因此,您通常希望将与顶点相关的每一条数据拟合到一个块中(位置、法线、切线、所有纹理坐标、镜面反射度等),每个块都存储在绝对最低精度的容器中。如果您使用非常小的GPU(如OpenGL ES中通常使用的GPU),那么尽可能多地保留隐式并重新计算它通常会更便宜—例如,存储一个双分量法线,并根据法线在99.9999%的所有引擎中存储为单位长度的约束,在着色器中计算出第三个法线。

它会影响多少需要的记忆。但这通常很好。为了优化OpenGL,建议您使用一个包含一组属性的数组,将其加载到视频内存中一次,然后重新使用该数组(即通过设置步长使用数组的特定属性,以便跳过其他属性)。这样可以更快地将多个阵列加载到视频内存中。可能会有所不同。正如@Cornstalks所指出的,不仅是您使用的内存量,还包括读取的内存量,以及相应地在顶点获取过程中缓存丢失的数量。假设顶点提取程序使用64字节的缓存线大小。在第一个示例中,数据以每个顶点12字节的速度打包,您将以单个缓存未命中的代价读取5个以上的顶点。如果数据中存在未使用的填充,则可能会导致更多缓存未命中和更多内存读取。这很少会成为瓶颈,但可能会增加开销。看来我现在不行了@Cornstales和Reto Koradi,谢谢。低精度容器,如struct of Float,而不是double?是的,甚至更小-例如,
GL[u]字节
是颜色和正常组件的标准。这就是在指定步幅之前,normalise标志的主要用途。
struct VertexData2 d2;
glVertexAttribPointer(index, 3, GL_FLOAT, GL_FALSE, sizeof(struct VertexData2), &d2.x);