Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Color, making it union  (Read 11144 times)

0 Members and 2 Guests are viewing this topic.

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #15 on: September 19, 2011, 09:22:19 am »
Quote from: "Laurent"
Quote
Also if having a set of 4 GLubytes instead of an array is undefined bahaviour this is also the case in sfml. Al you do in OpenGL is pass a Glubyte pointer to the beginning of the data and it is read in direct succession. So I can be as sure as Laurent that four GLubyte is contained within a 4byte integer. If it wasn't the case neither of our implementations would work.

SFML doesn't use vertex arrays (yet), the color is used in a call to glColor4ub(r, g, b, a).

what about GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
Doesn't glTexSubImage2D read 32 bits at a time?
This is SFML1.6. Do you do it differently in 2.0?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
sf::Color, making it union
« Reply #16 on: September 19, 2011, 11:15:05 am »
Indeed, the small speed gain is neither relevant in the big picture nor worth all the trouble it brings. Sometimes this is also called premature optimization.

I think myPixels is an std::vector<sf::Uint8>, i.e. an array of bytes, so there is no problem. As already stated, arrays guarantee subsequent element addresses, in contrast to separate members.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #17 on: September 19, 2011, 11:27:52 am »
Quote from: "Nexus"
Indeed, the small speed gain is neither relevant in the big picture nor worth all the trouble it brings. Sometimes this is also called premature optimization.

I think myPixels is an std::vector<sf::Uint8>, i.e. an array of bytes, so there is no problem. As already stated, arrays guarantee subsequent element addresses, in contrast to separate members.

No it's not

mutable std::vector<Color> myPixels;

So it only guarantees no padding between Color elements not in between elements inside Color.

Also, I have found no troubles with this method.
Please list them.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::Color, making it union
« Reply #18 on: September 19, 2011, 11:37:33 am »
In SFML 2 it's an array of UInt8.

Quote
Also, I have found no troubles with this method.
Please list them.

If the compiler decides to insert padding between the members you're screwed up.
Laurent Gomila - SFML developer

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #19 on: September 19, 2011, 11:54:25 am »
Quote from: "Laurent"
In SFML 2 it's an array of UInt8.

Quote
Also, I have found no troubles with this method.
Please list them.

If the compiler decides to insert padding between the members you're screwed up.

But then so is SFML 1.6, and it has worked for countless people. So it doesn't seem to happen that often.

I guess I should look into alignment more, does anyone have any good sources?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::Color, making it union
« Reply #20 on: September 19, 2011, 12:04:52 pm »
It's still very dangerous because it can change from compiler to compiler, and making a slight modification to the class may completely change the padding which is applied to it.

A few examples (with my compiler):
Code: [Select]
struct bop
{
    char x1;
    char x2;
    char x3;
    char x4;
};

sizeof(bop) == 4, no padding

Code: [Select]
struct bop
{
    short s;
    char x1;
    char x2;
    char x3;
    char x4;
};

sizeof(bop) == 6, no padding

Code: [Select]
struct bop
{
    char x1;
    short s;
    char x2;
    char x3;
    char x4;
};

sizeof(bop) == 8, padding!
Laurent Gomila - SFML developer

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #21 on: September 19, 2011, 12:17:34 pm »
I read about that yesterday. And for this specific case it's not very dangerous since we will only ever use 32bits. No more, no less.

Are there any compilers out there that would make
struct Color{ byte r,g,b,a; };
sizeof(Color) == 16 bytes??? or even 8bytes
It's difficult finding data on this.

In other cases with more data involved it's obviously a bad thing to mess around with.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::Color, making it union
« Reply #22 on: September 19, 2011, 12:24:49 pm »
I think we could have sizeof(sf::Color) == 16, yes, if the compiler decides to align each member on the size of int. Int is the most natural (and thus faster) type to manipulate for the processor, and padding often consists of aligning data at offsets multiple of sizeof(int). So the probability to have sizeof(sf::Color) == 16 is not negligible.
Laurent Gomila - SFML developer

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #23 on: September 19, 2011, 12:35:11 pm »
I concede that it's a possibility. But is it probable? Has it ever happened and if so with which compilers?

I mean even if it's possible doesn't mean it happens. I mean everyone uses unsigned char for allocating bytes of data, and there is no guarantee that  it's 1byte large. Still people use it since there isn't a compiler that implements it differently.

Glubyte is a typedef for unsigned char. And so is BYTE under windows and so is alot of other macros by other companies.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::Color, making it union
« Reply #24 on: September 19, 2011, 01:11:38 pm »
Quote
I concede that it's a possibility. But is it probable? Has it ever happened and if so with which compilers?

I don't know, but anyway I wouldn't rely on it.

Quote
I mean even if it's possible doesn't mean it happens. I mean everyone uses unsigned char for allocating bytes of data, and there is no guarantee that it's 1byte large. Still people use it since there isn't a compiler that implements it differently.

Glubyte is a typedef for unsigned char. And so is BYTE under windows and so is alot of other macros by other companies.

Correct me if I'm wrong, but I think that the definition of byte is sizeof(char) (or rather the other way round: a char is defined by having a size of one byte). What can be different is the size of one byte in bits: it may not always be 8.
Laurent Gomila - SFML developer

Silvah

  • Guest
sf::Color, making it union
« Reply #25 on: September 19, 2011, 04:22:08 pm »
Quote from: "Bozemoto"
Are there any compilers out there that would make
struct Color{ byte r,g,b,a; };
sizeof(Color) == 16 bytes??? or even 8bytes
No. In fact, no practical compiler would even try do to that, that's a huge waste of memory. Since these are bytes, on all platforms I've ever heard of they have natural alignment of 1. So they're accessed equally fast no matter where they lie.

Nexus and Laurent are basically playing language lawyers here. And I actually agree with them on this one. Seriously, how much you'd gain? A thousand cycles in the whole run of the program? That's nothing on modern hardware. Heck, that's nothing even on very old hardware (and by very old I mean the things from '70s)! You're really wasting your time trying to optimize this. Furthermore, your code depends on undefined behavior. That's quite bad.

Quote from: "Laurent"
That was just an example. The point is that there's no guarantee that it can fill a 32-bits integer.
My point is that there's no guarantee that it couldn't fill a 32-bit integer, either ;)
Moreover, what's more important, someone could see that and begin to think that RAND_MAX is 65536 everywhere. It'd be safer to write something like "let's suppose RAND_MAX is 65536..." ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::Color, making it union
« Reply #26 on: September 19, 2011, 04:28:24 pm »
Quote
Moreover, what's more important, someone could see that and begin to think that RAND_MAX is 65536 everywhere. It'd be safer to write something like "let's suppose RAND_MAX is 65536..."

Of course. Sometimes I use shortcuts that are... too short ;)
Laurent Gomila - SFML developer

Bozemoto

  • Newbie
  • *
  • Posts: 12
    • View Profile
sf::Color, making it union
« Reply #27 on: September 19, 2011, 05:14:16 pm »
Quote from: "Silvah"
Seriously, how much you'd gain? A thousand cycles in the whole run of the program? That's nothing on modern hardware.

True, it's not a significant gain. But it is fun to play around with things like this. Previous to this thread I had given little thought to data alignment, though I'm not saying I'll always do it in the future.

I think I'll read up on union behaviour a bit, I wont be returning to the thread anymore as I think there is little more to discuss. I appreciate all the feedback I've gotten and wish you all luck with your respective projekts.

Bye.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
sf::Color, making it union
« Reply #28 on: September 19, 2011, 07:12:15 pm »
Quote from: "Laurent"
Correct me if I'm wrong, but I think that the definition of byte is sizeof(char) (or rather the other way round: a char is defined by having a size of one byte).
You are right; char, signed char and unsigned char are among the few types in C++ with a fixed size ;)

Quote from: "Bozemoto"
True, it's not a significant gain. But it is fun to play around with things like this.
That is true, you learn a lot about low-level mechanisms like memory layout and data alignment/padding. C++ is anyway a language in which you can endlessly experiment around and find unorthodox solutions. Just take a look at Boost ;)

In productive code however, I wouldn't take the risk of undefined behavior for no effective advantage (it is extremely unlikely that this is the performance bottleneck of your application).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: