Main Page | Report this Page
 
Computers Forum Index  »  Computer Languages (Misc)  »  New release of the Dynace OO extension to C...
Page 8 of 8    Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8

New release of the Dynace OO extension to C...

Author Message
Tech07...
Posted: Sun Aug 02, 2009 8:16 am
Guest
Richard Herring wrote:
Quote:
In message <blocm.37761$0z7.25121 at (no spam) newsfe07.iad>, Tech07
tech07 at (no spam) nospam.hia> writes

"Juha Nieminen" <nospam at (no spam) thanks.invalid> wrote in message
news:Xsjcm.117$9g2.94 at (no spam) read4.inet.fi...
Tech07 wrote:

but yes, C++ wrapper objects on the stack are very convenient for
this (though probably not as efficient since there is a ctor and
dtor call).

There's nothing in constructors and destructors which would make
them less efficient than equivalent C solutions. (For example an
object with an empty inline constructor will probably produce no
code at all.)

Oh? A ctor call will be required for every auto-destroying object in
a function.


Why? If the compiler can deduce that calling the constructor will have
no effect on observable behaviour, which it certainly can if the
constructor i's inline and empty, by the "as-if" rule (ISO/IEC
14882:2003 1.9/1 [intro.execution]) it is under no obligation to call
it.

So your stated has "achieved" putting a jump to a label into the compiler.
Whoo hoo~!!
 
Tech07...
Posted: Sun Aug 02, 2009 8:18 am
Guest
BGB / cr88192 wrote:
Quote:
"Tech07" <tech07 at (no spam) nospam.hia> wrote in message
news:w%5dm.95231$eS5.48829 at (no spam) newsfe25.iad...
BGB / cr88192 wrote:
"Jerry Coffin" <jerryvcoffin at (no spam) yahoo.com> wrote in message
news:MPG.24dbea4f260cff2198971a at (no spam) news.sunsite.dk...
In article <h4tcbv$apv$1 at (no spam) aioe.org>, jacob at (no spam) nospam.org says...

Jerry Coffin wrote:

The basic problem being dealt with is pretty simple. In C, you
run into two problems. First of all, about the only thing C
provides for dealing with dynamic data is
malloc/calloc/realloc/free. Second, it makes it essentially
impossible to centralize the use of those tools.

The lcc-win C compiler provides a GC. This allows for much easier
programming what memory management is concerned. You just
replace malloc by GC_malloc, and forget about free

In theory, almost any C compiler could include a GC -- but most
don't, and portable code certainly can't count on it. Of course,
the same is true in C++.

More less orthogonally, while GC works quite nicely for memory (at
least in some situations) it does nothing at all for managing other
resources (file handles, handles to GUI stuff, etc.)


often, a GC is written for and used by the app in question.
it being provided by a compiler, then, is a convinience...


Why is it, that when a GC thread emerges, that I feel like
spray-painting on it?

I don't know...

either way, the technology works well for what it does...

Stop spray-painting over my posts!
 
Tech07...
Posted: Sun Aug 02, 2009 8:22 am
Guest
BGB / cr88192 wrote:
Quote:
"Tech07" <tech07 at (no spam) nospam.hia> wrote in message
news:NV5dm.24356$sC1.1248 at (no spam) newsfe17.iad...
jacob navia wrote:
Jerry Coffin wrote:

The basic problem being dealt with is pretty simple. In C, you run
into two problems. First of all, about the only thing C provides
for dealing with dynamic data is malloc/calloc/realloc/free.
Second, it makes it essentially impossible to centralize the use
of those tools.

The lcc-win C compiler provides a GC.

You say that as if it was a lucrative feature. (hint, hint: not to
me!).
This allows for much easier
programming what memory management is concerned.

Programming without memory management isn't programming. ;)

You just
replace malloc by GC_malloc, and forget about free

Keywords one hears all over the place: "you just...". Well,
personally, "I don't wanna just.. " anything. :P

Trying to sell "you don't have to think about it!" to thinkers (yes,
the IQ on here is way above the average Joe/Jane) on USENET is
doomed to failure. I suggest you not pursue a marketing career, cuz
you really suck at it.


in my case, I use a GC, but typically treat it like a manual memory
manager. why? because that typically gives higher performance and
more desirable runtime behavior...

"youth is wasted on the young" !
 
Nick Keighley...
Posted: Sun Aug 02, 2009 3:14 pm
Guest
On 1 Aug, 18:33, Juha Nieminen <nos... at (no spam) thanks.invalid> wrote:
Quote:
Nick Keighley wrote:
well, you've got to write your destructors correctly.

  I think you are just trying to rationalize how RAII doesn't *really*
bring any benefit compared to manual scope management,

nope. I consider RAII to be one C++s good points. I'm simply saying
people (or people from a C background) don't just stumble upon
RAII on their own (well most people). RAII is a coding convention.

Quote:
as if it was
completely equivalent to have to perhaps write a destructor once and
have the compiler call it automatically from every place where the
object is used, and to have to basically inline destructors manually at
each usage point.

  Besides, you are missing the point: "Writing destructors correctly" is
not a coding convention to *get around a limitation* in the language.
It's using a language feature for its intended purpose and to help
reduce the amount of coding conventions needed in the program.
 
Richard Herring...
Posted: Mon Aug 03, 2009 12:47 pm
Guest
In message
<455c8a62-bbc1-4351-9027-c04af303855c at (no spam) r38g2000yqn.googlegroups.com>,
Nick Keighley <nick_keighley_nospam at (no spam) hotmail.com> writes
Quote:
On 31 July, 16:46, Juha Nieminen <nos... at (no spam) thanks.invalid> wrote:
Nick Keighley wrote:

what coding conventions does C typically use that C++ typically
doesn't? Isn't the use of RAII a massive coding convention?

  No. RAII is certainly not a coding convention. It's a compiler
technique and has little to do with coding conventions. A coding
convention is something the *programmer* does, while RAII is something
the *compiler* does automatically.

well, you've got to write your destructors correctly.
I'd say using RAII correctly was very much a programmer
thing.

void process_pdu (const byte* pdu, size_t size)
{
Msg* msg = new Msg (pdu, size);
process_msg (msg);
delete msg;
}


C++ isn't Java:

void process_pdu(const byte * pdu, size_t size)
{
Msg msg(pdu, size);
process_msg(&msg);
// look, no delete needed!
}

--
Richard Herring
 
Richard Herring...
Posted: Mon Aug 03, 2009 12:51 pm
Guest
In message <9q8dm.95349$eS5.91179 at (no spam) newsfe25.iad>, Tech07
<tech07 at (no spam) nospam.hia> writes
Quote:
Richard Herring wrote:
In message <blocm.37761$0z7.25121 at (no spam) newsfe07.iad>, Tech07
tech07 at (no spam) nospam.hia> writes

"Juha Nieminen" <nospam at (no spam) thanks.invalid> wrote in message
news:Xsjcm.117$9g2.94 at (no spam) read4.inet.fi...
Tech07 wrote:

but yes, C++ wrapper objects on the stack are very convenient for
this (though probably not as efficient since there is a ctor and
dtor call).

There's nothing in constructors and destructors which would make
them less efficient than equivalent C solutions. (For example an
object with an empty inline constructor will probably produce no
code at all.)

Oh? A ctor call will be required for every auto-destroying object in
a function.


Why? If the compiler can deduce that calling the constructor will have
no effect on observable behaviour, which it certainly can if the
constructor i's inline and empty, by the "as-if" rule (ISO/IEC
14882:2003 1.9/1 [intro.execution]) it is under no obligation to call
it.

So your stated has "achieved" putting a jump to a label into the compiler.

Illucid. Please try again, in English next time.

Quote:
Whoo hoo~!!



--
Richard Herring
 
BGB / cr88192...
Posted: Mon Aug 03, 2009 10:18 pm
Guest
"Richard Herring" <junk at (no spam) [127.0.0.1]> wrote in message
news:CUpY4bCTQqdKFwaa at (no spam) baesystems.com...
Quote:
In message
455c8a62-bbc1-4351-9027-c04af303855c at (no spam) r38g2000yqn.googlegroups.com>,
Nick Keighley <nick_keighley_nospam at (no spam) hotmail.com> writes
On 31 July, 16:46, Juha Nieminen <nos... at (no spam) thanks.invalid> wrote:
Nick Keighley wrote:

what coding conventions does C typically use that C++ typically
doesn't? Isn't the use of RAII a massive coding convention?

No. RAII is certainly not a coding convention. It's a compiler
technique and has little to do with coding conventions. A coding
convention is something the *programmer* does, while RAII is something
the *compiler* does automatically.

well, you've got to write your destructors correctly.
I'd say using RAII correctly was very much a programmer
thing.

void process_pdu (const byte* pdu, size_t size)
{
Msg* msg = new Msg (pdu, size);
process_msg (msg);
delete msg;
}


C++ isn't Java:

or... maybe it is... or at least judging from some of the C++ code I have
seen floating around...


Quote:

void process_pdu(const byte * pdu, size_t size)
{
Msg msg(pdu, size);
process_msg(&msg);
// look, no delete needed!
}


yep...

since, in this case, the object sits on the stack...

Quote:
--
Richard Herring
 
luserXtrog...
Posted: Tue Aug 04, 2009 5:57 am
Guest
On Aug 1, 11:22 pm, "Tech07" <tec... at (no spam) nospam.hia> wrote:
Quote:
BGB / cr88192 wrote:
"Tech07" <tec... at (no spam) nospam.hia> wrote in message
news:NV5dm.24356$sC1.1248 at (no spam) newsfe17.iad...
jacob navia wrote:

You just
replace malloc by GC_malloc, and forget about free

Keywords one hears all over the place: "you just...". Well,
personally, "I don't wanna just.. " anything. :P

Trying to sell "you don't have to think about it!" to thinkers (yes,
the IQ on here is way above the average Joe/Jane) on USENET is
doomed to failure. I suggest you not pursue a marketing career, cuz
you really suck at it.

in my case, I use a GC, but typically treat it like a manual memory
manager. why? because that typically gives higher performance and
more desirable runtime behavior...

"youth is wasted on the young" !

Is wisdom wasted on the aged?

--
[gratuitous inane transformation of ostensibly meaningless pseudonym]
txl
 
Tech07...
Posted: Tue Aug 04, 2009 8:42 am
Guest
"Richard Herring" <junk at (no spam) [127.0.0.1]> wrote in message
news:iFqAMLEeUqdKFwfZ at (no spam) baesystems.com...
Quote:
In message <9q8dm.95349$eS5.91179 at (no spam) newsfe25.iad>, Tech07
tech07 at (no spam) nospam.hia> writes
Richard Herring wrote:
In message <blocm.37761$0z7.25121 at (no spam) newsfe07.iad>, Tech07
tech07 at (no spam) nospam.hia> writes

"Juha Nieminen" <nospam at (no spam) thanks.invalid> wrote in message
news:Xsjcm.117$9g2.94 at (no spam) read4.inet.fi...
Tech07 wrote:

but yes, C++ wrapper objects on the stack are very convenient for
this (though probably not as efficient since there is a ctor and
dtor call).

There's nothing in constructors and destructors which would make
them less efficient than equivalent C solutions. (For example an
object with an empty inline constructor will probably produce no
code at all.)

Oh? A ctor call will be required for every auto-destroying object in
a function.


Why? If the compiler can deduce that calling the constructor will have
no effect on observable behaviour, which it certainly can if the
constructor i's inline and empty, by the "as-if" rule (ISO/IEC
14882:2003 1.9/1 [intro.execution]) it is under no obligation to call
it.

So your stated has "achieved" putting a jump to a label into the compiler.

Illucid. Please try again, in English next time.

Whoo hoo~!!


I too don't know where I was going with that.
 
Richard Bos...
Posted: Tue Aug 04, 2009 11:03 pm
Guest
luserXtrog <mijoryx at (no spam) yahoo.com> wrote:

Quote:
On Aug 1, 11:22=A0pm, "Tech07" <tec... at (no spam) nospam.hia> wrote:
"youth is wasted on the young" !

Is wisdom wasted on the aged?

Wisdom is wasted on all humans, regardless of their age and which
language they choose to program in.

Richard
 
Blake McBride...
Posted: Wed Aug 05, 2009 1:08 am
Guest
Juha Nieminen wrote:
Quote:
Blake McBride wrote:
Objects are allocated in blocks and chopped up so there is virtually no
malloc overhead. For example, if an object without malloc overhead
takes up 32 bytes, when one object is allocated I might allocate 320
bytes (enough for 10). I'd then return one. The next time you new'ed
one up I'd just cut another piece off. The malloc overhead is once for
the all 10 (and of course I could have allocated 100, etc.). Freein up
an object amounts to just linking it back to the chunk so it is very
fast. Allocations are usually simple unlinks and free's amount to
one-line re-links.

Where do you store the pointer to the allocated block (with space to
store 10 objects), the pointer to the first free object in that block,
and the counter for the amount of allocated objects in that block (which
is necessary to free the block if all the objects inside it are freed)?

The class object contains a pointer to an instance block. That instance
block contains a pointer to the next instance block, etc.. An instance
block may contain an arbitrarily large number of instances with zero
overhead per instance (since we are keeping track of instance blocks
rather than instances). The only overhead is once per block.

The class also keeps a pointer to a free instance. The free instance
points to the next free instance, and so-on. Instances must know what
they are an instance of so each instance has enough room for a pointer
to the class it is an instance of. This pointer is used to keep the
track of the free list when the instance is not used. Thus, no memory
overhead.


Quote:

If the object has a vtable pointer in it (in the cases where the
language needs it), that adds the size of one pointer to the object size
behind the scenes.
vtables are associated with the class not the instances.

That would be incorrect. You have to store a pointer to the vtable on
each instance if you want dynamic binding to work. That's why C++ does
it (don't you think that C++ would avoid doing that if it wasn't
absolutely necessary?). Thus dynamic binding increases the size of each
object by one pointer.

It doesn't matter whether an instance points to a class which in-turn
points to a vtable, or if the instance points directly to the vtable.
The point I was making is that there is only one vtable per class, not a
distinct vtable per instance.

Quote:

The number of
instances does not affect the vtable size at all.

And who claimed it does?

In this particular example (ie. the "Pixel" class consisting of 4
bytes) the object itself, when allocated dynamically, would require 16
bytes of memory in a (32-bit) Linux system, plus the pointer used to
handle it. Thus each 'Pixel' object requires 20 bytes of memory. And
this assuming the vtable pointer is not needed. If that is needed by the
language, then each object requires 24 bytes of memory.

In C++, in the optimal case (as the one I gave as example, ie. no
dynamic binding needed, a std::vector<Pixel> as data container), each
object requires only 4 bytes of memory. (And this is so even in 64-bit
systems.)

Of course lesser memory usage is not the only advantage: Allocating 10
million objects dynamically, one at a time, is very expensive, even when
using some optimized memory allocator. C++ classes allow allocating all
the 10 million objects as one single memory block (which is what the
std::vector in the example does), in other words, there is only one
allocation rather than 10 million. This is a HUGE time saver.
This happens even if you allocate one too - not just when you allocate
an array of them.

"This"? What "this"?
 
Juha Nieminen...
Posted: Fri Aug 07, 2009 1:02 am
Guest
Blake McBride wrote:
Quote:
The class object contains a pointer to an instance block. That instance
block contains a pointer to the next instance block, etc.. An instance
block may contain an arbitrarily large number of instances with zero
overhead per instance (since we are keeping track of instance blocks
rather than instances). The only overhead is once per block.

The problem with having zero overhead per instance is that when you
delete such an instance (using a pointer to the instance), there's no
way of knowing (using that pointer-to-the-instance) which block the
instance belongs to (at least not in constant time). Thus there's no
easy way of adding the space taken by that instance to the proper list
of free instances.

Of course you could have only one single list of free instances in the
entire program, but then it's not possible to free blocks from the
system memory (because there's no way of knowing, at least in constant
time, whether they still have live instances or not).

Quote:
The class also keeps a pointer to a free instance. The free instance
points to the next free instance, and so-on. Instances must know what
they are an instance of so each instance has enough room for a pointer
to the class it is an instance of.

That's not "zero overhead". That's having an overhead of one pointer
per instance. (In other words, besides the block allocating space for
the instances, it additionally allocates space for one pointer per
instance. That's overhead.)

Quote:
If the object has a vtable pointer in it (in the cases where the
language needs it), that adds the size of one pointer to the object
size
behind the scenes.
vtables are associated with the class not the instances.

That would be incorrect. You have to store a pointer to the vtable on
each instance if you want dynamic binding to work. That's why C++ does
it (don't you think that C++ would avoid doing that if it wasn't
absolutely necessary?). Thus dynamic binding increases the size of each
object by one pointer.

It doesn't matter whether an instance points to a class which in-turn
points to a vtable, or if the instance points directly to the vtable.
The point I was making is that there is only one vtable per class, not a
distinct vtable per instance.

That's what I said originally in the quote above: "that adds the size
of one pointer to the object size", to which you objected that "vtables
are not associated with the instances" which seemed to claim that what I
said was wrong.

My original point stands: In OO languages where every object supports
dynamic binding, every object has an overhead of at least one pointer
behind the scenes (thus potentially doubling the size of an object which
would otherwise contain only eg. an integer member).
 
Blake McBride...
Posted: Sun Aug 09, 2009 4:38 pm
Guest
Juha Nieminen wrote:
Quote:
Blake McBride wrote:
The class object contains a pointer to an instance block. That instance
block contains a pointer to the next instance block, etc.. An instance
block may contain an arbitrarily large number of instances with zero
overhead per instance (since we are keeping track of instance blocks
rather than instances). The only overhead is once per block.

The problem with having zero overhead per instance is that when you
delete such an instance (using a pointer to the instance), there's no
way of knowing (using that pointer-to-the-instance) which block the
instance belongs to (at least not in constant time). Thus there's no
easy way of adding the space taken by that instance to the proper list
of free instances.

Of course you could have only one single list of free instances in the
entire program, but then it's not possible to free blocks from the
system memory (because there's no way of knowing, at least in constant
time, whether they still have live instances or not).

The class also keeps a pointer to a free instance. The free instance
points to the next free instance, and so-on. Instances must know what
they are an instance of so each instance has enough room for a pointer
to the class it is an instance of.

That's not "zero overhead". That's having an overhead of one pointer
per instance. (In other words, besides the block allocating space for
the instances, it additionally allocates space for one pointer per
instance. That's overhead.)

All that you are saying above is true. Dynace instances do not have
pointers to the storage block they came from. While Dynace allow the
user to free and re-use memory taken up by instances, it does not, in
constant time, auto-free entire blocks. So there is zero overhead with
the designed limitation that the entire block wouldn't be freed, at
least in constant time.

Quote:

If the object has a vtable pointer in it (in the cases where the
language needs it), that adds the size of one pointer to the object
size
behind the scenes.
vtables are associated with the class not the instances.
That would be incorrect. You have to store a pointer to the vtable on
each instance if you want dynamic binding to work. That's why C++ does
it (don't you think that C++ would avoid doing that if it wasn't
absolutely necessary?). Thus dynamic binding increases the size of each
object by one pointer.
It doesn't matter whether an instance points to a class which in-turn
points to a vtable, or if the instance points directly to the vtable.
The point I was making is that there is only one vtable per class, not a
distinct vtable per instance.

That's what I said originally in the quote above: "that adds the size
of one pointer to the object size", to which you objected that "vtables
are not associated with the instances" which seemed to claim that what I
said was wrong.

My original point stands: In OO languages where every object supports
dynamic binding, every object has an overhead of at least one pointer
behind the scenes (thus potentially doubling the size of an object which
would otherwise contain only eg. an integer member).
 
Juha Nieminen...
Posted: Sun Aug 09, 2009 6:00 pm
Guest
Blake McBride wrote:
Quote:
All that you are saying above is true. Dynace instances do not have
pointers to the storage block they came from. While Dynace allow the
user to free and re-use memory taken up by instances, it does not, in
constant time, auto-free entire blocks. So there is zero overhead with
the designed limitation that the entire block wouldn't be freed, at
least in constant time.

According to my own memory manager experiments keeping a global list
of freed objects and reusing them in the same (or reverse) order in
which they were freed, and never freeing entire blocks, often causes a
speed penalty.

The reason is not immediately obvious, but very clear: If you simply
keep a list of freed objects (in the order in which they are freed), the
objects in this list will often get very randomized with respect to
their location in memory. In other words, when you traverse the list of
free objects, you will be randomly jumping over a large range of memory.
The cache miss penalties this produces cause a very considerable
slowdown to this custom memory allocation.

When you free entire blocks of memory at a time, what happens is that
when that memory is needed again for new objects, the allocator will
allocate the block again and start using it *in linear order*. This
makes it very cache-friendly and fast.

According to my tests we are not talking about something like 10-20%
speedup. We are talking about something like 100-300% speedup. If not
even more.

(Unless I'm completely mistaken, I think one idea with the so-called
compacting garbage collectors is precisely this: They compact and
reorder used and freed memory blocks so that further allocations will
happen as linearly as possible, making it very cache-efficient. This is
one of the reasons why this type of memory allocator is so fast, even
though it performs additional work on the background from time to time.
Any time spent in compacting is often vastly compensated by faster
allocation.)
 
David Thompson...
Posted: Mon Aug 10, 2009 5:17 am
Guest
On Thu, 30 Jul 2009 19:08:13 GMT, Juha Nieminen
<nospam at (no spam) thanks.invalid> wrote:

Quote:
Flash Gordon wrote:

I would certainly declare them static to help the optimiser
unless there was a good reason not to.

In some cases a static local variable can actually be less efficient
than a stack-allocated variable. This is because the compiler has to add
a conditional which checks whether this is the first time that static
variable is reached or not. Conditionals are generally slower than
incrementing some stack pointer.

In C++ for local static of a type with a ctor. (Maybe only a

nontrivial ctor, I can never remember exactly what is trivial.)

For C++ just-data-init, and all C, static initialization occurs
'before' startup (in practice, at compile/link time).

Quote:
(Also if the static variable is a huge data container, if you don't
clear it when exiting the function, it becomes basically "leaked".)

And if it's just statically large, like a (C) array rather than
std::vector, you don't even have the ability to release it.
 
 
Page 8 of 8    Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8
All times are GMT
The time now is Sun Nov 22, 2009 5:26 am