Any optimization technique regarding efficient use of memory spacefor class/Union types?

G

Good Guy

I'd like to be aware of any possible optimization you people know in
terms of efficient memory usage by objects of class/Union types, like
somebody mentioned to me There are some rules about two objects having
same or overlapping memory addresses but not with any detail.
 
A

Amarpreet Singh

I'd like to be aware of any possible optimization you people know in
terms of efficient memory usage by objects of class/Union types, like
somebody mentioned to me There are some rules about two objects having
same or overlapping memory addresses but not with any detail.

I didnt get your problem exactly.. Only shallow copying of class
object pointers point to same memory.
 
J

Jim Langston

Good Guy said:
I'd like to be aware of any possible optimization you people know in
terms of efficient memory usage by objects of class/Union types, like
somebody mentioned to me There are some rules about two objects having
same or overlapping memory addresses but not with any detail.

Well, you should be aware of variable sizes if memory is a big issue for
you. Compilers will normally add padding bytes to make variables line up
correctly. For example, a 4 byte integer may want to start on every 4th
byte. Some interger types break in fact if they are aligned wrong.
Consider a structure in which we have 2 1 byte chars and 2 4 byte integers.
We can do it a few ways:

struct foo {
char c1;
char c2;
int i1;
int i2;
};

struct bar {
int i1;
char c1;
int i2;
char c2;
};

Doesn't seem like it should make a difference, right? Do a sizeof on both
of these and you shoudl find that the sizeof foo is 12 and the sizeof bar is
16. Huh? Where did those 4 bytes go? This is how it lines up in memory:

foo:
1 byte for c1
1 byte for c2
2 padding bytes to make int line up
4 bytes for int i1
4 bytes for int i2

1 + 2 + 2 + 4 + 4 = 12.

bar:
4 bytes for i1
1 byte for c1
3 padding bytes to make int line up
4 bytes for int i2
1 byte for char c2
3 padding bytes to make whole struct line up

4 + 1 + 3 + 4 + 1 + 3 = 16
Without those last 3 padding bytes the size would of been 13. If you have 2
of these structures in an array bar x[2]; the system has to ensure that
everythign lines up, so that is why the 3 bytes at the end, to make i1
always start on a evenly divisible by 4 boundary.

I don't know all the rules, and they may change from system to system from
compiler to compiler from year to year. But what I generally stick with is:
The system is going to line somethign up based on it's size. A char is size
1, so it doesn't matter. A short is size 2, so every other byte, or every
even bit. 4 btye ints line up on 4 bytes, etc...

Normally you don't need to worry about these rules, but you need to be aware
about them. Soemtimes you may try to read binary data into a structure and
wonder why things aren't lining up right.
 
L

Larry Evans

On 10/19/10 05:10, Jim Langston wrote:
[snip]
struct foo {
char c1;
char c2;
int i1;
int i2;
};

struct bar {
int i1;
char c1;
int i2;
char c2;
};

Doesn't seem like it should make a difference, right? Do a sizeof on
both of these and you shoudl find that the sizeof foo is 12 and the
sizeof bar is 16. Huh? Where did those 4 bytes go? This is how it
lines up in memory:

foo:
1 byte for c1
1 byte for c2
2 padding bytes to make int line up
4 bytes for int i1
4 bytes for int i2

1 + 2 + 2 + 4 + 4 = 12.

bar:
4 bytes for i1
1 byte for c1
3 padding bytes to make int line up
4 bytes for int i2
1 byte for char c2
3 padding bytes to make whole struct line up

4 + 1 + 3 + 4 + 1 + 3 = 16
Without those last 3 padding bytes the size would of been 13. If you
have 2 of these structures in an array bar x[2]; the system has to
ensure that everythign lines up, so that is why the 3 bytes at the end,
to make i1 always start on a evenly divisible by 4 boundary.

A related question occurred here:

http://lists.boost.org/Archives/boost/2010/10/171964.php

The corresponding driver for Jim's example produces output:

-------------------------
foo
===========
***components***
----------------
num size align sum_size
1 1 1 1
2 1 1 2
3 4 4 6
4 4 4 10
***composite***
---------------
num size align pad sum_pad offset
5 12 4 0 0 _
4 12 4 0 0 8
3 8 4 2 2 4
2 2 1 0 2 1
1 1 1 0 2 0
0 0 1 _ _ _
-------------------------
bar
===========
***components***
----------------
num size align sum_size
1 4 4 4
2 1 1 5
3 4 4 9
4 1 1 10
***composite***
---------------
num size align pad sum_pad offset
5 16 4 3 3 _
4 13 4 0 3 12
3 12 4 3 6 8
2 5 4 0 6 4
1 4 4 0 6 0
0 0 1 _ _ _

The driver is attached. Warning,
you have to use g++ with variadic templates
enabled and:

http://svn.boost.org/svn/boost/sandbox/variadic_templates/

HTH.

-Larry
 
G

Good Guy

I'd like to be aware of any possible optimization you people know in
terms of efficient memory usage by objects of class/Union types, like
somebody mentioned to me There are some rules about two objects having
same or overlapping memory addresses but not with any detail.

Well, you should be aware of variable sizes if memory is a big issue for
you.  Compilers will normally add padding bytes to make variables line up
correctly.  For example, a 4 byte integer may want to start on every 4th
byte.  Some interger types break in fact if they are aligned wrong.
Consider a structure in which we have 2 1 byte chars and 2 4 byte integers.
We can do it a few ways:

struct foo {
    char c1;
    char c2;
    int i1;
    int i2;

};

struct bar {
   int i1;
   char c1;
   int i2;
   char c2;

};

Doesn't seem like it should make a difference, right?  Do a sizeof on both
of these and you shoudl find that the sizeof foo is 12 and the sizeof bar is
16.  Huh?  Where did those 4 bytes go?  This is how it lines up in memory:

foo:
  1 byte for c1
  1 byte for c2
  2 padding bytes to make int line up
  4 bytes for int i1
  4 bytes for int i2

1 + 2 + 2 + 4 + 4 = 12.

bar:
   4 bytes for i1
   1 byte for c1
   3 padding bytes to make int line up
   4 bytes for int i2
   1 byte for char c2
   3 padding bytes to make whole struct line up

4 + 1 + 3 + 4 + 1 + 3 = 16
Without those last 3 padding bytes the size would of been 13.  If you have 2
of these structures in an array bar x[2]; the system has to ensure that
everythign lines up, so that is why the 3 bytes at the end, to make i1
always start on a evenly divisible by 4 boundary.

I don't know all the rules, and they may change from system to system from
compiler to compiler from year to year.  But what I generally stick with is:
The system is going to line somethign up based on it's size.  A char is size
1, so it doesn't matter.  A short is size 2, so every other byte, or every
even bit.  4 btye ints line up on 4 bytes, etc...

Normally you don't need to worry about these rules, but you need to be aware
about them.  Soemtimes you may try to read binary data into a structure and
wonder why things aren't lining up right.

Lets get this right:
foo:
1 byte for c1
1 byte for c2
2 padding bytes to make int line up
4 bytes for int i1
4 bytes for int i2

1 + 2 + 2 + 4 + 4 = 12.
last line should be->1 + 1 + 2 + 4 + 4 = 12
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top