is there a performance difference between vertexpointer alignment, if...

i’m thinking about the best way to structure vertex/uvcoords/normal data for a mesh class:

i came on two differenct conclusions:

  1. the first way would be:
    struct vertex
    {
    float x,y,z;
    float u,v;
    float nx,ny,nz;
    };
    and then having a: “vertex *vertexlist” in the mesh-class.

  2. the second way would be:
    (within the class “Cmesh”)
    class Cmesh {
    float *vertexcoords;
    float *uvcoords;
    float *normalcoords;
    }
    and then accessing each vertex by “vertexindex *3 + [0,1,2]”, each uvcoord by “vertexindex *3 + [0,1,…]” and each normalcoord by “vertexindex *3 + [0,1,2]” IF each vertex has its own normal and own set of uvcoord
    (to think about this conclusion let us assume, that it is so)

now my question is:
is there a (significant) performance difference between these two ways ?
i have read on processor structure and cache beahvior, so the second way seems to be better, because the cache would work more efficient - is that correct ??

It will only be a (notable) performance difference if it’s a bottle neck. Try it and see what happens for you, on your particular computer, with your program. The result will vary depending on system setup.

I would say the frist one is slightly more cache friendly, but I don’t know for sure. When you access a vertex, you also access the corresponding normal and texture coordinate, and if you can pack them together in an interleaved array, you could get away with less cache misses. But as I said, this is not my strongest area.

Bob,

i forgot to mention that i’m using vertex arrays; ant while setting up the difference array-pointer by using “gl…Pointer(…)” i thought, that i prepare the card, to read the vertex/uv/normal within one stream, or not ???

Originally posted by DJSnow:
[b]Bob,

i forgot to mention that i’m using vertex arrays; ant while setting up the difference array-pointer by using “gl…Pointer(…)” i thought, that i prepare the card, to read the vertex/uv/normal within one stream, or not ???[/b]

What does “prepare the card” mean?

Originally posted by DJSnow:
[b]Bob,

i forgot to mention that i’m using vertex arrays; ant while setting up the difference array-pointer by using “gl…Pointer(…)” i thought, that i prepare the card, to read the vertex/uv/normal within one stream, or not ???[/b]
Ummm, yes, kind of

As with so many fun things, it depends.
Do you always (or rather most of the time) access all vertex elements at the same time?
Do you, most of time, submit the complete vertices (coord, tex coord, normal), or do you frequently disable one of these?

If you really use everything, all the time, you should IMO go interleaved. It’s simpler and more bandwidth efficient to set up a single stream than to set up three. Prefetch hardware will work better, too.

If you frequently just send the vertex positions, the remaining parts of the vertex structure will be dead weight clogging up your memory bus.

Your call

@V-man:

>>What does “prepare the card” mean?
this means setting up the array-pointer on my mesh-data, to tell the card/driver that it has to read the vertex data from that or that or that position.
i have used this word (maybe at the wrong place) to tell you what i’m doing. sorry for this small misplacement.

@zeckensack:

>>Do you always (or rather most of the >>time) access all vertex elements at the >>same time?
yes, i have to access all vertex/uvcoord/normal data all the same time - because all objects use their vertexpos, their normal and their uvcoords

>>Do you, most of time, submit the complete
>>vertices (coord, tex coord, normal), or
>>do you frequently disable one of these?
you mean be “letting some vertices of one mesh out” ? no, i always draw the meshes complete.

Personally, i’m against the use of interleaved arrays. I don’t think there’s a real performance gain but what I know for sure is that they are not being updated anymore.

what I know for sure is that they are not being updated anymore.

Precisions + sources please ?

Y.

What Obli means with “interleaved arrays not being updated” is that the specs haven’t changed for a long time for the InterleavedArray call. I agree; it’s an outmoded concept and I’d be surprised to see any more work on the existing API.

However, I do believe that there may be performance benefits to be had from aligning array pointers on hardware-friendly boundaries (cache lines, or at least 64-bit word lines, etc). Also, I believe that there’s still hardware out there that can only deal with two, or perhaps even only one, stream efficiently.

A single stream is also likely cache better for many software transform implementations. You’re not ignoring chips like the i845 “Intel Extreme 3D Graphics” are you? Big market.

Originally posted by Obli:
Personally, i’m against the use of interleaved arrays. I don’t think there’s a real performance gain but what I know for sure is that they are not being updated anymore.
True, the glInterleavedArrays interface hasn’t seen any updating. This isn’t particularly relevant, because, if you check the documentation for glInterleavedArrays, it’s simply a wrapper on top of gl*Pointer calls.

Extending this interface further would lead to “enumerant explosion”, which is traditionally regarded as a bad thing. IMO that’s the sole reason for the lack of progress there.

OTOH it doesn’t matter. You can construct any interleaved vertex stream format you want with the basic gl*Pointer calls.

Originally posted by DJSnow:
[b]@zeckensack:

>>Do you always (or rather most of the >>time) access all vertex elements at the >>same time?
yes, i have to access all vertex/uvcoord/normal data all the same time - because all objects use their vertexpos, their normal and their uvcoords[/b]
So, when you change your vertex data, you, in general, change vertex positions and tex coords and normals? Did I get that right?

In that case an interleaved format will lead to better bandwidth utilitzation on the chipset front, and to fewer cache line fetches on the processor front.

>>Do you, most of time, submit the complete
>>vertices (coord, tex coord, normal), or
>>do you frequently disable one of these?
you mean be “letting some vertices of one mesh out” ? no, i always draw the meshes complete.

That’s not what I meant

I wanted to ask whether you frequently draw the geometry without tex coords and/or normals. Ie
glDisableClientState(GL_TEXTURE_COORD_POINTER);
glDisableClientState(GL_NORMAL_POINTER);
glDrawElements …

That’s sometimes useful (especially for application driven deferred shading, eg when doing stencil shadows). Obviously, the more data you ‘skip’ the more bandwidth you’ll lose (because memory works best w long bursts).

@zeckensack:

>>change vertex positions and tex coords >>and normals? Did I get that right?
oh no ! with the sentence “…do you always access the at the time…” i thought, that you meant if i “use” them each frame to render them; i don’t mean modifying, only rendering them. and, to make this clear: no, i don’t change the data all the time.

>>That’s not what I meant
ooh, yes, no i understand:
but the answer is “few partially”, let me say, there are 10 meshes in one scene - then a maximum of 2 or 3 meshes don’t use its normals/uvdata, the rest of it will be rendered “normal” (~fully, with all data).

[This message has been edited by DJSnow (edited 07-22-2003).]