a[3} slower than a.x; a.z; a.z

G

Gernot Frisch

Is it faster to define a vertex structure by .x .y .z members instead
of [3] array?

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
N

Niels Dybdahl

Is it faster to define a vertex structure by .x .y .z members instead
of [3] array?

Not if you use constants for indexing into the array. But .x .y .z might be
more readable.

Niels Dybdahl
 
C

Catalin Pitis

Niels Dybdahl said:
Is it faster to define a vertex structure by .x .y .z members instead
of [3] array?

Not if you use constants for indexing into the array. But .x .y .z might
be
more readable.

Niels Dybdahl

Use the arrays. It allows you to apply transformations using matrix
operations. There shouldn't be much difference of performance between
indexing through constants and member access.

Catalin
 
J

JKop

Gernot Frisch posted:
Is it faster to define a vertex structure by .x .y .z members instead
of [3] array?


int blah[3];


struct Blah
{
int x;
int y;
int z;
} blah;



Only difference I can fathom:


The implementation may *not* put padding between array elements, while it
*may* put padding between structure elements.

(And before some-one says it... YES I do realize that there wouldn't be
padding between "int"s in anyway! :p)


-JKop
 
G

Gernot Frisch

Use the arrays. It allows you to apply transformations using matrix
operations. There shouldn't be much difference of performance
between indexing through constants and member access.

Phew. I did the right thing :)
I think a good compiler will perform the +index internally.
 
I

Ioannis Vranos

JKop said:
int blah[3];


struct Blah
{
int x;
int y;
int z;
} blah;



Only difference I can fathom:


The implementation may *not* put padding between array elements, while it
*may* put padding between structure elements.


If you mean an int in an array can not have padding bits, you are wrong.


(And before some-one says it... YES I do realize that there wouldn't be
padding between "int"s in anyway! :p)


What do you mean?
 
J

JKop

If you mean an int in an array can not have padding bits, you are
wrong.


I'm implying that there must not be padding *between* the elements of an
array. The actual elements *themselves* can contain as much padding as they
want.


int blah[3];

int* p_b = blah;

++p_b ;


"p_b" is now *guaranteed* to point to the second element of the array.


struct Blah
{
int a;
int b;
int c;
} blah;


int* p_b = &(blah.a);


++p_b;


"p_b" is *not* guaranteed to point to "blah.b". Why? There may be padding.

What do you mean?


The whole thing about padding is so that certain types are aligned a certain
way in memory.

Well... "int" is the natural type for the machine, so all the "int"s that
follow will be nicely aligned without padding.


-JKop
 
G

Gernot Frisch

JKop said:
If you mean an int in an array can not have padding bits, you are
wrong.


I'm implying that there must not be padding *between* the elements
of an
array. The actual elements *themselves* can contain as much padding
as they
want.


int blah[3];

int* p_b = blah;

++p_b ;


"p_b" is now *guaranteed* to point to the second element of the
array.


struct Blah
{
int a;
int b;
int c;
} blah;


int* p_b = &(blah.a);


++p_b;


"p_b" is *not* guaranteed to point to "blah.b". Why? There may be
padding.

I was thinking additional memory used for alinging ia _always_
appended at the end of the structure, thus p_b == &blah.b. If not, I
really have to think about some code lines now...
 
R

Ron Natalie

JKop said:
The implementation may *not* put padding between array elements, while it
*may* put padding between structure elements.
Another difference harkens to the fact that arrays are bastard types.

typedef int BlahArray[3];
struct BlahStruct { int x, y, z; };

BlahArray l, r;
l = r; // ill-formed
BlahStruct l, r;
l = r; // does what is expected.

Further, you can always have constructors and other helpful
members in Blah. This is C++ after all.
 
R

Ron Natalie

Ioannis said:
If you mean an int in an array can not have padding bits, you are wrong.
There can not be padding bits in an array OTHER than those in the types
that the array is made of.

That is: sizeof (T[n]) is always equal to n * sizeof (T).
 
U

Unforgiven

Ron Natalie said:
JKop said:
The implementation may *not* put padding between array elements, while it
*may* put padding between structure elements.
Another difference harkens to the fact that arrays are bastard types.

typedef int BlahArray[3];
struct BlahStruct { int x, y, z; };

BlahArray l, r;
l = r; // ill-formed
BlahStruct l, r;
l = r; // does what is expected.

Further, you can always have constructors and other helpful
members in Blah. This is C++ after all.

Best of both worlds?

class Vertex
{
private:
int points[3];
public:
int x() const
{
return points[0];
}
int y() const
{
return points[1];
}
int z() const
{
return points[2];
}
};

This way you can access the Vertex by its more readable x,y,z syntax from
the outside, and still implement efficient matrix transformations in member
(or friend) functions. Too bad C# doesn't support property syntax, that
would've been even better.
 
I

Ioannis Vranos

JKop said:
If you mean an int in an array can not have padding bits, you are
wrong.



I'm implying that there must not be padding *between* the elements of an
array. The actual elements *themselves* can contain as much padding as they
want.


int blah[3];

int* p_b = blah;

++p_b ;


"p_b" is now *guaranteed* to point to the second element of the array.


struct Blah
{
int a;
int b;
int c;
} blah;


int* p_b = &(blah.a);


++p_b;


"p_b" is *not* guaranteed to point to "blah.b". Why? There may be padding.



C90 mentions:

"There may also be unnamed padding at the end of a structure or
union, as necessary to achieve the appropriate alignment were the
structure or union to be a member of an array."



C++98 mentions:

"[Note: There might therefore be unnamed padding within a POD-struct
object, but not at its beginning, as necessary to achieve appropriate
alignment. ]"


Now this confuses me. Is the second a redefinition of the first, and
thus leaving it open paddings to be anywhere except the beginning too?

Or is it a restatement of something that already applies in C90 too.

The whole thing about padding is so that certain types are aligned a certain
way in memory.

Well... "int" is the natural type for the machine, so all the "int"s that
follow will be nicely aligned without padding.


The only types guaranteed to have no padding bits are char and unsigned
char.
 
G

Gernot Frisch

Best of both worlds?

Is there a way of using "union" for this? Just out of curriosity. I
like [0] instead of .x
It's just as you are used to it.
 
I

Ioannis Vranos

Unforgiven said:
Best of both worlds?

class Vertex
{
private:
int points[3];
public:
int x() const
{
return points[0];
}
int y() const
{
return points[1];
}
int z() const
{
return points[2];
}
};

This way you can access the Vertex by its more readable x,y,z syntax
from the outside, and still implement efficient matrix transformations
in member (or friend) functions. Too bad C# doesn't support property
syntax, that would've been even better.


Since it looks like you have C# in mind, here is C++/CLI code for a ref
type with such properties that produces 100% safe IL code (binary
portability):


ref class Vertex
{
private:
cli::array<int> ^points;

public:

Vertex(): points(gcnew array<int>(3)) {}

property int x
{
int get() { return points[0]; }
void set(int x) { points[0] = x; }
}

property int y
{
int get() { return points[1]; }
void set(int x) { points[1] = x; }
}

property int z
{
int get() { return points[2]; }
void set(int x) { points[2] = x; }
}
};



int main()
{
Vertex v;

v.x=6;
}



Personally I like the array syntax, and if I wanted to make the array
private here we are:


ref class Vertex
{
private:
cli::array<int> ^points;

public:

Vertex(): points(gcnew array<int>(3)) {}

property int Points[unsigned]
{
int get(unsigned i) { return points; }
void set(unsigned i, int new_value) { points = new_value; }
}
};



int main()
{
Vertex v;

v.Points[2]=6;
}
 
R

Ron Natalie

Gernot said:
Best of both worlds?


Is there a way of using "union" for this? Just out of curriosity. I
like [0] instead of .x
It's just as you are used to it.
Don't think so... You'd need some sort of anonymous struct which doesn't
exist in C++.
 
U

Unforgiven

Hmm, now that's a Freudian slip... I was thinking C++ doesn't support
property syntax and C# does, but ended up combining the thoughts into the
false statement you see above.
Since it looks like you have C# in mind, here is C++/CLI code for a ref
type with such properties that produces 100% safe IL code (binary
portability):

I haven't dabbled with C++/CLI yet. Main reason for it is I didn't use
Managed C++ much either. If I want to write managed code, I'll write VB.NET
or C#, if I want unmanaged code, I'll write C++. If and only if I needed
managed code to interact with unmanaged code so closely that it would've
resulted in VB.NET code riddled with System.InteropServices.Marshal class
member calls or C# code filled with unsafe blocks, would I resort to using
Managed C++.

And besides, since the OP was concerned with the performance difference
between array indexing and struct member access in C++, undoubtably he'd
find managed code too slow. ;)
 
G

Gernot Frisch

And besides, since the OP was concerned with the performance
difference between array indexing and struct member access in C++,
undoubtably he'd find managed code too slow. ;)

I'd never touch anything "higher" than C++
 
I

Ioannis Vranos

Unforgiven said:
Hmm, now that's a Freudian slip... I was thinking C++ doesn't support
property syntax and C# does, but ended up combining the thoughts into
the false statement you see above.



I haven't dabbled with C++/CLI yet. Main reason for it is I didn't use
Managed C++ much either. If I want to write managed code, I'll write
VB.NET or C#, if I want unmanaged code, I'll write C++. If and only if I
needed managed code to interact with unmanaged code so closely that it
would've resulted in VB.NET code riddled with
System.InteropServices.Marshal class member calls or C# code filled with
unsafe blocks, would I resort to using Managed C++.

And besides, since the OP was concerned with the performance difference
between array indexing and struct member access in C++, undoubtably he'd
find managed code too slow. ;)


C++/CLI is far better and more powerful than C#/CLI (that's the "C#"),
and is oriented as the systems programming language of CLI (and .NET).



Some things to mention:

1) Deterministic destruction / managed objects with stack semantics

2) All C++ features available for CLI types (e.g. templates). All CLI
features available in C++ (e.g. generics).


VC++ oriented:
3) More optimisation in the produced code. PGO optimisation.
4) More hand optimisation - OMP multithreading support

5) Ability to mix managed and unmanaged types freely, inherit managed
types from unmanaged, unmanaged from managed, unmanaged objects in the
managed heap, managed type objects in the native heap - VC++ support for
that in the release after 2005.


C++/CLI: Correct by default.

Other languages (including C#/CLI): Correct by explicit coding



References:

http://microsoft.sitestream.com/TechEd/DEV/DEV333_files/Botto_files/DEV333_Sutte.ppt

http://www.accu.org/conference/pres...Relevant_on_Modern_Environments_(keynote).pdf

http://groups.google.com/groups?hl=en&lr=&[email protected]

And my C++/CLI page: http://www23.brinkster.com/noicys/cppcli.htm
 
J

JKop

Ron Natalie posted:
Gernot said:
Best of both worlds?


Is there a way of using "union" for this? Just out of curriosity. I
like [0] instead of .x
It's just as you are used to it.
Don't think so... You'd need some sort of anonymous struct which doesn't
exist in C++.

Thinking about that...

Let's say you had a load of code that defined anonymous structs throughout
(for instance, windows header files). Given the following definition:

union Blah
{
int k;

struct
{
int t;
float r;
};
};


(which I actually like, and I don't know why anonymous structs are
outlawed...)

Anyway, I wonder if a program which parsed it and came out with the
following would do the job?:


class Blah
{
private:

union
{
int k;

struct
{
int t;
float r;
} anonymous1;
} the_union;

public:

int& t;
float& r;
int& k;

Blah() : t( the_union.anonymous1.t ), r( the_union.anonymous1.r ), k(
the_union.k ) {}
};


Hmm... something to throw on top of the "Macro Destroyer" pile I suppose...


-JKop


Consider if this were in a header file. The source files which make use of
it would be unaffected, and everything would compile Standard C++
compliantly.


-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top