Topic: tweaking the virtual function table pointer


Author: "=?iso-8859-1?B?RnJhbmstUmVu6SBTY2jkZmVy?=" <frank_r_schaefer@gmx.net>
Date: 24 Sep 2005 04:20:26 GMT
Raw View
Case:

   -- class X has occupies tiny amount of memory:

            sizeof(X) is only a little greater than sizeof(void*).

   -- X instantiates thousands of objects and memory does matter.

   -- The class has a virtual destructor, and therefore, a pointer
      to a virtual function table.

   -- This class, now, needs a boolean variable 'boolF' which would
      cost at the very least 1 byte, which is a lot under the
      circumstances described above.

   --> idea: (1) copy the virtual function table at another place.

             (2) let the virtual function pointer point to either
                 one of the virtual function tables (which are
                 identical), but:

                 The place where the pointer points to indicates the
                 state of the 'implicitly represented' variable
                 'boolF'.

      Such a setup is profitable, if

              N * sizeof(bool) > sizeof(virtual function table),

      where N = estimated number of instantiated objects.

Does the standard impose the management of virtual function tables
strictly enough to elaborate on such a solution? Is such a
solution practical?

Thanks

Frank

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bart@ingen.ddns.info (Bart van Ingen Schenau)
Date: Sat, 24 Sep 2005 16:28:27 GMT
Raw View
Frank-Ren=E9 Sch=E4fer wrote:

<snip - scheme to use multiple instances of a v-table to represent the
state of some data member>
=20
> Does the standard impose the management of virtual function tables
> strictly enough to elaborate on such a solution?

The standard does not mandate the use of virtual function tables at all.
The standard only says that such-and-such construct must behaver in a
particular way. It is up to the compiler writers to figure out how they
can achieve the required behaviour.
It just so happens that v-tables are a straightforward way of
implementing the mechanics of virtual functions, but I don't think it
is the only way.

> Is such a solution practical?

I don't think so. Your solution does not scale to multiple members that
can be encoded with this technique. Think about the number of v-tables
needed for 3 or 4 boolean fields.
And your solution applies only to a very specialised field, so compiler
writers will most likely ignore this kind of optimisation as long as
there are other optimisations possible that are more generally
applicable.

>=20
> Thanks
>=20
> Frank
>=20
Bart v Ingen Schenau
--=20
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 24 Sep 2005 16:28:45 GMT
Raw View
"Frank-Ren=E9 Sch=E4fer" <frank_r_schaefer@gmx.net> writes:

> Does the standard impose the management of virtual function tables
> strictly enough to elaborate on such a solution?=20

The standard says nothing about vtbls.  An implementation is not even
required to use them.  What you propose would be a conforming
implementation.

> Is such a solution practical?

:)

In the sense of "will I ever be able to get a compiler vendor to
implement this?"  I would guess no, because demand probably isn't high
enough.  However, you might try one of the vendors targeting embedded
systems, such as Metrowerks.

Good Luck!

--=20
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Sat, 24 Sep 2005 16:31:23 GMT
Raw View
Frank-Ren=E9 Sch=E4fer wrote:
>=20
> Does the standard impose the management of virtual function tables
> strictly enough to elaborate on such a solution? Is such a
> solution practical?
>=20

AFAIK, the standard introduces the notion of virtual function but it
doesn't specify how the desired effect needs to be implemented. In
particular, it doesn't even say that it must be implemented using
virtual tables, even if that's the most obvious approach. Therefore, I
believe the answer to both your questions is no.

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richard@ex-parrot.com
Date: Tue, 27 Sep 2005 10:18:46 CST
Raw View
Frank-Ren    Sch   fer wrote:

[snip ingenious scheme to represent data with vptrs]

> Is such a solution practical?

Let's look at this piece of code:

  struct X {
    virtual ~X() {}
    bool b;
  };

  void fn(bool volatile&);

  int main() {
    X x;
    fn(x.b);
  }

How does the compiler get a reference to X::b?  Presumably it'll have
to construct a temporary, something like this:

  int main() {
    X x;
    bool tmp(x.b); fn(tmp); x.b = tmp;
  }

What if fn() throws an exception?  We still need to set x.b, so:

  int main() {
    X x;
    bool tmp(x.b);
    try { fn(tmp); } catch(...) { x.b = tmp; throw; }
    x.b = tmp;
  }

What about in multithreaded code?  It should be possible to guarantee
that X::b has been set by a given point in fn().  (Depending on what
the platform guarantees about threading, this may require some form of
locking primitive.)  How should the compiler cope with this
possibility?

--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Tony Delroy" <tony_in_da_uk@yahoo.co.uk>
Date: Tue, 27 Sep 2005 10:22:03 CST
Raw View
Hi Frank,

I've found it useful in the past to avoid directly giving objects
runtime polymorphic behaviour (to save memory, due to shared memory
usage, concurrent access & packing), preferring to have a polymorphic
pointer-to-object class.  If you do this, your thousands of objects
don't need virtual dispatch pointers, and yet you get the convenience
of run-time polymorphic handling.  You use a simple factory method
(your classes can embed a type code much smaller than a void*) -
possibly returning a derived type cloned from a reference object (as
per the flyweight pattern).

Cheers,

Tony

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: wade@stoner.com
Date: Tue, 27 Sep 2005 15:35:04 CST
Raw View
Frank-Ren    Sch   fer wrote:
>       Such a setup is profitable, if
>
>               N * sizeof(bool) > sizeof(virtual function table),
>
>       where N = estimated number of instantiated objects.

This relation is only correct in the case that no other classes are
actually derived from X.  Otherwise you've got to double all of the
derived classes' vtables also (or thunk accesses to the bool, so that
base class and derived class can use different implementations).

The implementation would also have to worry about the case where the
bool bits were set to an indeterminate value:

class X
{
  bool foo;
  virtual int bar(); // bar may not read-access foo
};

void foobar(X& x)
{
  memset(&x.foo, rand(), sizeof(x.foo));

  // Virtual dispatch needs to work, no matter what bits are in foo.
  x.bar();
}

There are better space optimizations available.  If the implementation
is able to determine (smart linker, build option, ...) that only a
small number of derived classes exist, it can save more space by using
a smaller vtable 'pointer'.  For example if fewer than 255 concrete
classes are derived from X, the vtable pointer could be replaced by a
one-byte index into an array of vtable pointers.  If no classes are
derived from X, then the vtable pointer may be implicit, requiring no
per-instance space at all.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]