c++ VTable size calculation

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys,
There have been many discussions over years about the desirability and/or ease of implementing VTables in flash rather than RAM.

The reality seems to be that this is unlikely to happen.

I recently implemented a class with one virtual method. The overhead was 8 bytes per instance.

I can understand 2 bytes being a pointer to the actual method in the derived class. 8 bytes surprised me.

are there some dimensioning rules somewhere that would let me calculate VTable sizes?

I couldn't find any with the help of Google or the forum search.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not study the .s and the .lss and find out how the 8 bytes are being used?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

good suggestion. I had a go at this some time ago and at that stage couldn't figure it out. :(

I will have another go at answering my own question but thought that probably someone already knew the answer.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

While the number is increasing there still aren't that many using C++ and of those who are I fear finding someone who's explored the vtable mechanism could be tricky so you may be at the bleeding edge on this one.

Next time I'm near a computer I'd be interested to look myself. Presumably the code just needs to define a base class with one or more virtual functions then derive and instantiate a class from this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are we actually talking about an increase of 8 bytes RAM? Or is it an increased flash cost you've seen?

If RAM I speculate that part of the cost could be for RTTI.

Quote:
Next time I'm near a computer I'd be interested to look myself.

+1, but Cliff is so much better at reading disassembly and the LSS, and I have a small USB experiment in the pipe, so I'll leave it to him.. :D

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Are we actually talking about an increase of 8 bytes RAM? Or is it an increased flash cost you've seen?

If RAM I speculate that part of the cost could be for RTTI.


Definitely 8 bytes of RAM. Flash cost is relatively small for some indirection.

I had to google RTTI=Run-time type info. gosh that's a bit more complex than I wanted to think about!

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nothing more than some ID, perhaps a name, and perhaps a pointer to the base class(es) vtable(s). E.g. info to make possible type-safe casts where the type of the object cast is not known at compile-time".

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is an interesting example, and a good explanation too, here: http://stackoverflow.com/questio...

[Holy Crap! I was not CAPTCHAd for the link above!!]

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Stuff in the vtable is per type, not per instance.
Absent multiple inheritance, I'd expect each instance to have one vtable pointer.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh.. I never noticed the "per instance" in the OP. Now the additional cost seems really strange..

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indeed.... I think you are right.

I have done some more tests and there is quite a big overhead per class and then a small overhead per instance.

I will post some more details as I start to see a pattern.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

a small overhead per instance

Every object needs to point to its vtable(s).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With the example below I found that if I commented out all of the virtual functions then the ram usage was 1 byte per instance as expected.

with one virtual function the ram usage was 16 bytes for one instance, 19 for 2 and 22 for 3. ie 1 byte for "b"and then 2 bytes overhead.

With 2 virtual functions and 1/2/3 instances the ram usage was 20/23/27 bytes.

With 3 virtual functions and 1/2/3 instances the ram usage was 24/27/30 bytes.

class baseClass
{
	public:
	unsigned char b;
	baseClass(void);
	void bFunc1(void);
	void bFunc2(void);
	virtual void vFunc1(void){};
	virtual void vFunc2(void){};
	virtual void vFunc3(void){};
};


class aClass : public baseClass
{
	public:
	aClass(void);
	void vFunc1(void);
	void vFunc2(void);
	void vFunc3(void);
};

In summary in my example if storage for "b"is excluded:-
cost per class is
- 11 bytes overhead + (=?)
- 4 bytes/virtual function (=pointer to function + ?)
cost per instance is
- 2 bytes overhead (=pointer to vtable)

I guess that the "11"above is 10 bytes plus a word alignment padding of 1 byte.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use -fdump-class-hierarchy to produce a file that will show more info about what's taking up space in the class.

Are you using -fno-rtti to get ride of the RTTI overhead?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks a lot. The class info is great and shows two unused ints at the beginning of each vtable.

the -fno-rtti did not seem to make any difference to the ram usage.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
Thanks a lot. The class info is great and shows two unused ints at the beginning of each vtable.

the -fno-rtti did not seem to make any difference to the ram usage.

One of the entries in the vtable (2nd) is for RTTI support. IIRC, -fno-rtti used to remove the entry but I just tried it again and doesn't seem to change anything.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks.

Do you know what the first entry is for?

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
Thanks.

Do you know what the first entry is for?

It's offset-to-top which has something do to with multiple inheritence.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

that looks like a definitive reference. It should stop me from asking more questions :D

regards
Greg