Re: [fpc-devel] Modernising Pascal

2005-02-27 Thread Jamie McCracken
DrDiettrich wrote:
Jamie McCracken wrote:

GC is very inefficient with memory and current implementations tend to
cost a lot performance wise too.

I don't see how GC is inefficient with memory?
Reference counting and (mark/sweep) garbage collection have a different
runtime behaviour: Reference counting occurs with many references to
objects, whereas GC only runs when required, or when idle time is left.

The problem with GC is the lifetime of (dead) objects is significantly 
extended under GC. This means it hogs more memory for much longer. 
Memory allocation is also potentially slowed as a result of more objects 
remaining allocated on the heap so less chance of holes appearing which 
can be reused (unless you use a compacting GC).

GC runs in a seperate thread so will incur additional overhead from that 
too and you cant always predict when it runs and it can snare you at the 
most inappropriate times (EG if memory is in short supply the thread 
must become extremeley aggressive to avoid swap so you will lose 
performance big time in those cases and with compacting variety even 
more so if it does end up in swap)




GC gets a lot slower with the more objects you create.

It's not the creation that costs GC time, instead it's the destruction
of the objects.
Its potentially both. All GCs have a tradeoff between memory usage and 
performance. A compacting one may have faster allocation but uses more 
memory as a result. There is no perfect GC that both uses memory 
efficiently and gives good performance (when compared to manual).



Mixing unmanaged with managed code cause severe performance issues
(marshalling penalties calling ummanaged c functions)
Interoperability with C gets increasingly difficult. Writing bindings
becomes much more complicated and time consuming.

IMO it's never a good idea to mix managed and unmanaged code, to suffer
from the worst from two worlds at the same time :-(

GC is worse here because the pointers are not static in GC so 
referencing an object means looking up the actual address in a lookup 
list (so more overhead whenever you call a method or pass an object 
reference). GC does not use the stack efficiently and has to use a lot 
of heap so its extremely inefficient. Ever see GC compact swap?

I don't know what GC implementation you're referring to. When memory
gets too much fragmented, every memory manager has to do a compaction,
that's inevitable. But GC offers a chance to update the references to
moved objects, so that no address tables are required. Other memory
managers don't know about the locations of pointers to the objects, so
that moving objects is not possible at all! Consequently GC allows for
better use of available memory, where other methods have to stop with
out of memory.
IMO you should learn a bit more about memory management, your
argumentation doesn't look well founded to me.
There are over a dozen different GC strategies so some of my points 
apply to some but not others (same with a lot of the replies here) thats 
why this thread has become long and controversial - you simply cant make 
 a lot of generalities without specifying which type of GC you are 
reffering to.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-27 Thread DrDiettrich
peter green wrote:

 one thing i have heared (i don't use garbage collected languages much so
 i've never seen this myself) is that the GC gets some CPU time and starts
 causing stuff to be swapped in. This slows other threads down which gives
 the GC more CPU and causes more stuff to be swapped in.

GC is started either when the system is (almost) idle, or when no more
memory is available for some request. In the first case nothing is
blocked by GC, and in the second case everything is blocked by
out-of-memory, until the GC has collected free memory.

 another effect that i have seen is when CPU usage is high a garbage
 collected app can suck up all the systems memory. It can get all the memory
 it needs for itself because it can force run its garbage collector when it
 runs out but no other app on the system can.

When GC runs in idle time, no other apps exist that could be blocked.
When GC must swap something into memory, then the system is equipped
with too little RAM for the current situation; in such a state
everything runs slowly, due to permanent swapping. I know that people
often discuss how to reduce swapping overhead, and typically they all
miss the simple solution that they should extend their RAM to prevent
swapping to occur at all.

 some objects may use resources other than memory which are more valuable and
 need to be freed asap.

Destructors (or finalizers) can be called to release no longer required
resources, even when GC is used. When it's known or suspected that an
object could be destroyed, the GC can be invoked immediately. GC for
itself doesn't eliminate all resource woes, of course. In special
situations it may make sense to support GC with additional code, just
like with any other memory management method (see below).

 refcounting doesn't suffer from any of theese issues

Reference counting has more critical problems, like zombie objects. GC
will always find and remove all dead objects, whereas reference counting
never can eliminate bidirectionally linked objects, as exist in a GUI
(parent - child controls).

 also note that use of const parameters can eliminate a huge amount of
 refcounting overhead.

I'm not sure about the real impact of const. And even if the use of
const parameters results in a significant runtime reduction, this only
indicates that much more runtime could be saved by not using reference
counting at all!

DoDi



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


RE: [fpc-devel] Modernising Pascal

2005-02-26 Thread peter green


 -Original Message-
 From: [EMAIL PROTECTED]
 [mailto:[EMAIL PROTECTED] Behalf Of DrDiettrich
 Sent: 26 February 2005 03:34
 To: FPC developers' list
 Subject: Re: [fpc-devel] Modernising Pascal


 Jamie McCracken wrote:

  GC is very inefficient with memory and current implementations tend to
  cost a lot performance wise too.

 I don't see how GC is inefficient with memory?
 Reference counting and (mark/sweep) garbage collection have a different
 runtime behaviour: Reference counting occurs with many references to
 objects, whereas GC only runs when required, or when idle time is left.

one thing i have heared (i don't use garbage collected languages much so
i've never seen this myself) is that the GC gets some CPU time and starts
causing stuff to be swapped in. This slows other threads down which gives
the GC more CPU and causes more stuff to be swapped in.

another effect that i have seen is when CPU usage is high a garbage
collected app can suck up all the systems memory. It can get all the memory
it needs for itself because it can force run its garbage collector when it
runs out but no other app on the system can.

some objects may use resources other than memory which are more valuable and
need to be freed asap.

refcounting doesn't suffer from any of theese issues

also note that use of const parameters can eliminate a huge amount of
refcounting overhead.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Sebastian Kaliszewski
On Thursday 24 February 2005 14:57, Jamie McCracken wrote:
  It's *much* faster than reference counting everything. Reference
  counting is more or less the slowest garbage collection technique there
  is (except if only very few objects have to garbage collected). It also
  can't deal with circular references.

 Thats why I would want ref count for Tobjects and not Tcomponents.
 Partial ref counting should be faster than doing GC on everything.

You could do partial GC as well. No one forces yo to do GC on everything.


  GC gets a lot slower with the more objects you create.
 
  Reference counting too.

 GC is worse here because the pointers are not static in GC.

Not true. There are GC's with static as well as unstatic pointers 
(compacting GC's move pointers, but there are not compating GC's as well). 
For example Bohm GC (for C) does not move pointers. And it's GC.


 so
 referencing an object means looking up the actual address in a lookup
 list

Nonsense. It's clear you don't know how typical GC works.


 (so more overhead whenever you call a method or pass an object
 reference).

Nope. 


 GC does not use the stack efficiently

Complete nonsense. GC has nothing to statck. Zero, null, nada...


 and has to use a lot
 of heap so its extremely inefficient.

More of the same... It's simply not true. 
Besides compacting GC supported directly by the langauge allows for 
extremely effective use of heap -- as effective as that of stack.


 Ever see GC compact swap?

Better go learn more:
http://www.iecc.com/gclist/GC-faq.html


 yes but with GC everything would have to be managed 

Nope. See above.


 whilst just ref
 counting Tobject would not cause these problems (you cant access a
 tobject from C anyhow). Tobject is the only weak point in Delphi's
 memory management so I would say using GC to correct that would be
 overkill.

Whatever. GC has different problems but you didn't touch any. 


PS. there exists real-time capable GC (i.e. good for (soft)real time 
applications, such thing can't be said about even most non GC memory 
allocation systems).

rgds
-- 
Sebastian Kaliszewski

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Sebastian Kaliszewski
On Thursday 24 February 2005 13:51, Jamie McCracken wrote:
  IMO the best solution for (almost) all of your problems were garbage
  collection. GC is part of Oberon, and it would fit into .NET/DotGNU as
  well.

 GC is very inefficient with memory and current implementations tend to
 cost a lot performance wise too.

This is simply not true.
If you don't belive then check the following:
1. Look with google for Quake rewrittiend into .Net (i.e. GC stuff) -- 
surprise surprise -- difference is neglibile (20%),
2. Look for Ocaml -- it's a heavyly GC-ed compiled language, and it's fast.



 GC gets a lot slower with the more objects you create.


No worse that normal memory allocation, if GC is implemented properly.


 Mixing unmanaged with managed code cause severe performance issues
 (marshalling penalties calling ummanaged c functions)

 Interoperability with C gets increasingly difficult. Writing bindings
 becomes much more complicated and time consuming.


I did wrote GC in C++ itself. So it binds rather well...


 GC is therefore a poor choice for a high performance language IMHO.

There are live examples to the contrary. If anything, then refcounting is a 
poor choice for such language -- it's really slow, and when multithreading 
avareness is needed then is terribly slow. Once I compared multithreading 
aware and surely well optimised boost++ refcounter with my primitive GC, 
the very samy app using unoptimised GC was 2 times faster.


In case of FPC main advantage of GC for autotatically managed stuff would be 
avoiding of putting the unwinding code by the compiler (those implicit try 
.. finally thigs). Main disadvantage is that moment of resource freeing is 
indefinite, and this would break exiting code (hence it's unacceptable).
 
rgds
-- 
Sebastian Kaliszewski


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Nico Aragón
El Viernes, 25 de Febrero de 2005 01:36, Sebastian Kaliszewski escribió:
 You could do partial GC as well. No one forces yo to do GC on everything.

Free Pascal object model is very flexible. If I'm not mistaken, it's 
compatible with Delphi so it has the same construction mechanism so it's 
possible to override InstanceSize, InitInstance, NewInstance and 
FreeInstance.

There is also a reference counting hooks for interfaces. Combining all these 
facilities, it's possible to create a parallel hierarchies of objects that 
use reference count or garbage collection.

-- 
saludos,

Nico Aragón


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Jamie McCracken
Sebastian Kaliszewski wrote:
On Thursday 24 February 2005 14:57, Jamie McCracken wrote:
It's *much* faster than reference counting everything. Reference
counting is more or less the slowest garbage collection technique there
is (except if only very few objects have to garbage collected). It also
can't deal with circular references.
Thats why I would want ref count for Tobjects and not Tcomponents.
Partial ref counting should be faster than doing GC on everything.

You could do partial GC as well. No one forces yo to do GC on everything.
You can but that would suck! Mixing unmanaged with managed code needs a 
lot of effort and the performance would be detrimental (marshalling of 
unmanaged objects/types).



GC gets a lot slower with the more objects you create.
Reference counting too.
GC is worse here because the pointers are not static in GC.

Not true. There are GC's with static as well as unstatic pointers 
(compacting GC's move pointers, but there are not compating GC's as well). 
For example Bohm GC (for C) does not move pointers. And it's GC.
I was referring to compacting GCs - non compacting ones are impractical 
to use unless you have tons of free memory and all the modern ones 
including .Net's generational one is incremently compacting.




so
referencing an object means looking up the actual address in a lookup
list

Nonsense. It's clear you don't know how typical GC works.
It does in compacting GCs (how else can you get the address of an object?)


(so more overhead whenever you call a method or pass an object
reference).

Nope. 
Yes for compacting GCs


GC does not use the stack efficiently

Complete nonsense. GC has nothing to statck. Zero, null, nada...
Exactly it has to use a managed heap which is slower! Unmanaged code can 
use the stack for greater speed. There is a lot of talk about GCs being 
almost as efficient as unmanaged code but I have never seen an 
implementation that comes close to that. C# and Java both have poor 
performance in large apps where you have lots of objects (delphi 2005 is 
also written in .net and it is very sluggish too).



and has to use a lot
of heap so its extremely inefficient.

More of the same... It's simply not true. 
Besides compacting GC supported directly by the langauge allows for 
extremely effective use of heap -- as effective as that of stack.
But heap is slower than stack.



Ever see GC compact swap?

Better go learn more:
http://www.iecc.com/gclist/GC-faq.html




yes but with GC everything would have to be managed 

Nope. See above.
In practice yes as above unless you can live with all the extra 
inefficiency.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Jamie McCracken
Sebastian Kaliszewski wrote:
On Thursday 24 February 2005 13:51, Jamie McCracken wrote:
IMO the best solution for (almost) all of your problems were garbage
collection. GC is part of Oberon, and it would fit into .NET/DotGNU as
well.
GC is very inefficient with memory and current implementations tend to
cost a lot performance wise too.

This is simply not true.
If you don't belive then check the following:
1. Look with google for Quake rewrittiend into .Net (i.e. GC stuff) -- 
surprise surprise -- difference is neglibile (20%),
2. Look for Ocaml -- it's a heavyly GC-ed compiled language, and it's fast.

Ocaml is a functional lanaguge. Procedural languages tend to not work as 
efficiently with GCs from what I have seen.



GC gets a lot slower with the more objects you create.

No worse that normal memory allocation, if GC is implemented properly.
Show me one that works properly with procedural lanaguages (java, C#, 
pascal etc) otherwise it just appears hypothetical. I dont doubt some 
languages are more suitable for this like LISP.




Mixing unmanaged with managed code cause severe performance issues
(marshalling penalties calling ummanaged c functions)
Interoperability with C gets increasingly difficult. Writing bindings
becomes much more complicated and time consuming.

I did wrote GC in C++ itself. So it binds rather well...
not a compacting one then - if we use compacting then you lose pointers 
and Pchars ergo all the existing bindings would be useless and would 
need to be rewritten manually (without the aid of H2pas!)


GC is therefore a poor choice for a high performance language IMHO.

There are live examples to the contrary. If anything, then refcounting is a 
poor choice for such language -- it's really slow, and when multithreading 
avareness is needed then is terribly slow. Once I compared multithreading 
aware and surely well optimised boost++ refcounter with my primitive GC, 
the very samy app using unoptimised GC was 2 times faster.
Okay maybe its not so clear cut but Im fairly sure that to implement 
things correctly we would have to GC everything and the overall overhead 
might cost more than a partial ref counting of some Tobjects.

However if your confident you can write a modern GC that would work very 
efficiently with FPC then by all means be my guest - I would be very 
interested to see it. Im not opposed to GC ing pascal if the 
performance/memory usuage is reasonably good.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Eric Grange
This is simply not true.
If you don't belive then check the following:
1. Look with google for Quake rewrittiend into .Net (i.e. GC stuff) -- 
surprise surprise -- difference is neglibile (20%),
Though if you study more what they compare, you'll find that their
.Net version is actually running at about half-speed of the commercial version,
as they only compare their .Net version against a non-.Net version of the
same code running under their compiler, and surprise surprise, to do that
they had to change enough of the code to register a significant perf drop.
Also, Quake isn't really a GC test as the code allocates most of its data
only once, and then almost never uses dynamic memory.
No worse that normal memory allocation, if GC is implemented properly.
Actually, that's incorrect, manual memory allocation has a constant
complexity cost if done properly (each alloc/free has a constant CPU
cost, whatever the amount of objects allocated or their size, just don't
use old fashioned linked-lists memory managers), while theoretically-
best-case-GC still isn't constant time (and practical ones are more
like O(n²)), GC memory allocation and heap compaction patterns are quite
cache unfriendly and will require partial or total freezes while they happen.
Eric
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Jamie McCracken
Florian Klaempfl wrote:
Jamie McCracken wrote:
I did wrote GC in C++ itself. So it binds rather well...

not a compacting one then - 

Ref. counting isn't compacting either?
Not an issue cause memory allocation is conventional when ref counting.
GCs allocate memory from a managed heap which fragments heavily ergo it 
needs compacting to be able to recycle free memory blocks more 
efficiently. (most GCs achieve fast memory allocation by always 
allocating from fresh untouched memory so you can quickly run out of 
memory if they dont compact exisiting used memory).

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Florian Klaempfl
Jamie McCracken wrote:
I did wrote GC in C++ itself. So it binds rather well...

not a compacting one then - 
Ref. counting isn't compacting either?
if we use compacting then you lose pointers 
and Pchars ergo all the existing bindings would be useless and would 
need to be rewritten manually (without the aid of H2pas!)

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Marco van de Voort
  This is simply not true.
  If you don't belive then check the following:
  1. Look with google for Quake rewrittiend into .Net (i.e. GC stuff) -- 
  surprise surprise -- difference is neglibile (20%),
 cost, whatever the amount of objects allocated or their size, just don't
 use old fashioned linked-lists memory managers), while theoretically-
 best-case-GC still isn't constant time (and practical ones are more
 like O(n?)), GC memory allocation and heap compaction patterns are quite
 cache unfriendly and will require partial or total freezes while they happen.

In the stories about old software that is updated or reimplemented with
GC/.NET/Java there are typical several caveats:

- the working set with boehm GC's is typically at least twice as large(good
rule of thumb) as manual allocation.  Using non GCed types, explicit GC
calls at timed points and setting refs to NIL can improve this slightly, but
this is tuning, not a fair comparison.
- Startup time is also nearly always affected severely, even if normal
   program execution is bearable
- Critical parts are often handoptimized by using a lot of non GCed types
(like int), this is not a typical programming method for these 
languages, but outright expert tuning.
- Older applications are often not CPU limited, but have a bottleneck 
somewhere else. So there is a hidden CPU performanceloss in the
comparison, since the managed app _is_ CPU limited apparently.
- (rare) HT/SMP usage.

Same with GC faqs. 



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Marco van de Voort
 On 25 feb 2005, at 15:49, Marco van de Voort wrote:
 
  - Critical parts are often handoptimized by using a lot of non GCed 
  types
  (like int), this is not a typical programming method for these
  languages, but outright expert tuning.
 
 Critical paths are also optimized in our compiler to not use 
 ansistrings, because reference counting is also slow.

And I was talking more specific about the Quake II benchmark that was
brought. Any tweaks would already be on top of the existing ones in the
code.

 The argument is not about whether or not we should make Pascal entirely
 GC'd, but about whether reference counting is better/worse than other
 garbage collection techniques if you have a significant amount of GC'd
 objects.

The Quake II benchmark was used to prove that full blown (I assume Boehm)
GC was not slow. Q II, as tuned app, is probably already using primitive
types heavily, thus not a poster child for this benchamark


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Sebastian Kaliszewski
On Friday 25 February 2005 15:18, Eric Grange wrote:
  No worse that normal memory allocation, if GC is implemented properly.

 Actually, that's incorrect, manual memory allocation has a constant
 complexity cost if done properly (each alloc/free has a constant CPU
 cost, whatever the amount of objects allocated or their size, just don't
 use old fashioned linked-lists memory managers),

1. This is not entirely true (the cost is at best logarithmic on the 
number of objects or your allocator has terrible fragmentation) 
2. You have to initialise your allocated data anyway.
3. In real life often you have virtual memory system underneath and there is 
no guarantee whatosoever.

 while theoretically-
 best-case-GC still isn't constant time

GC allocation (in case of compacting collecotr) is constant time trivially, 
all the cost is in compacting which is linear.

 (and practical ones are more
 like O(n²)),

Huh? If anything tracing is (trivially) O(m) where m is number of pointers 
of memory and in all but few contrived examples mn (where n is amount of 
allocated memory). Then most object die young so they are traced once. When 
you amortise the costs you'll see that tracing is allmost constant per 
object.

Then you can go for non tracing GC, use your nearly consttime 
alloc/dealloc and all the overhead is tracing (which is also nearly 
consttime per object)

 GC memory allocation and heap compaction patterns are quite
 cache unfriendly and will require partial or total freezes while they
 happen.

compacting GC allocation is rather more cache friendly than non GC one. 
Compacting Collection is not cache friendly though.


 Eric

rgds

-- 
Sebastian Kaliszewski

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Florian Klaempfl
Marco van de Voort wrote:

The argument is not about whether or not we should make Pascal entirely
GC'd, but about whether reference counting is better/worse than other
garbage collection techniques if you have a significant amount of GC'd
objects.

The Quake II benchmark was used to prove that full blown (I assume Boehm)
GC was not slow. Q II, as tuned app, is probably already using primitive
types heavily, thus not a poster child for this benchamark
Well, for a real Boehm test the FPC compiler should be used, I guess it makes a 
much more use of the heap than other apps :)

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Eric Grange
1. This is not entirely true (the cost is at best logarithmic on the 
number of objects or your allocator has terrible fragmentation) 
Not really, you can use a memory map and achieve much lower
fragmentation than classic memory managers (cf. FastMM submissions
in the FastCode project in the b.p.d.basm borland ng).
In practice, you're memory usage will be a lot lower than that
of a GC.
2. You have to initialise your allocated data anyway.
That's not a practical issue because:
- initialization may be a task of the user's code, thus doesn't
  fall to the memory manager
- you can use virtual memory facilities and have the initialization
  to zeroes happen automagically, no need to trash the CPU cache
  by explicitly filling with zeroes.
3. In real life often you have virtual memory system underneath and there is 
no guarantee whatosoever.
The management costs of the VM system are typically negligible if you
don't enter the realm of disk swapping, at which point the performance
of GC schemes completely collapses during garbage collections and compactions,
while a classic allocator can live perfectly happily with part of its
memory swapped out.
GC allocation (in case of compacting collecotr) is constant time trivially, 
Allocation is alway constant time whatever the allocator if you do it right,
that's not a comparison point, however, GC linear allocation isn't CPU-cache
friendly, meaning that if you get that memory fast, the first actions you'll
do on that memory will typically be an order of magnitude slower than if you
had been returned cached memory (particularly noticeable for allocations of
a few hundreds of kB of temporaries, string concatenations, growing arrays, 
etc.).
Another drawback of linear allocation is interleaving, which often reduces
the cache efficiency by placing heterogeneous data together (depends on
the application of course, but it can hit you rather severely on some
composite data structures).
 all the cost is in compacting which is linear.
Compacting might be linear, but it's cache unfriendly, which on a modern CPU
means an order of magnitude slower memory operations, and that happens
practically on the whole allocated memory. If some of it was swapped out,
you can then expect hell (I've seen it happen), and as compaction is a
necessity of linear allocation, you can never be 100% sure to avoid it
with a linearly allocating GC.
Finally garbage collection isn't a linear phase, and it's also intrinsically
not cache friendly (lots of random accesses all over the allocated memory,
most of which are going to be cache misses).
Nowadays, cache inefficiency can result in a lot of hidden perf hits,
with uncached accesses being 10 or more times slower (from CPU ratios,
RAM latencies, controler/chipset latencies, that all add to the CPU's
own L1/L2 latencies).
10 CPU cycles doesn't sound like much, but that's enough time for a dozen+
instructions under adequate circumstances, have it happen too often,
and that's enough to make the difference between smooth and sluggish.
Eric
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Sebastian Kaliszewski
On Friday 25 February 2005 17:29, Eric Grange wrote:
  1. This is not entirely true (the cost is at best logarithmic on the
  number of objects or your allocator has terrible fragmentation)

 Not really, you can use a memory map and achieve much lower
 fragmentation than classic memory managers

1. Memory map brings no quarantees of const time.
2. Same applies to GC managers. BTW GC can use the very same 
allocation/deallocation algorithm.

 (cf. FastMM submissions
 in the FastCode project in the b.p.d.basm borland ng).
 In practice, you're memory usage will be a lot lower than that
 of a GC.

You're forgetting internal fragmentation. It typical allocator allocating 
block with power of 2 sizes (4, 8, 16, 32, up to page size or small 
multiply of page size) assuming flat size distribution you have ~33% 
fragmentation.


  2. You have to initialise your allocated data anyway.

 That's not a practical issue because:
 - initialization may be a task of the user's code, thus doesn't
fall to the memory manager

But must happen anyway.

 - you can use virtual memory facilities and have the initialization
to zeroes happen automagically, no need to trash the CPU cache
by explicitly filling with zeroes.

No way. It does not. At best it's delayed up to the point when memory gets 
used actually rather than being just allocated. But then OS has to clear 
the page.


  3. In real life often you have virtual memory system underneath and
  there is no guarantee whatosoever.

 The management costs of the VM system are typically negligible

Neglibile but not const (they're mostly linear -- as memory must be cleared 
before porcess might use it -- due to basic security requirements).

 if you
 don't enter the realm of disk swapping, at which point the performance
 of GC schemes completely collapses during garbage collections

Modern generational GC's are less suspectible to such problems.

 and
 compactions,

Not every GC is compacting GC.

 while a classic allocator can live perfectly happily with
 part of its memory swapped out.

  GC allocation (in case of compacting collecotr) is constant time
  trivially,

 Allocation is alway constant time whatever the allocator if you do it
 right,

Nope. See above  below.
And even of you artificially restrict yourself to small span of small object 
sizes yuo have to check quite a bunch of conditions, and conditional 
branches are not free. It's allwayes order or two of magnitude slower than 
adding constant to a heap pointer.


 that's not a comparison point, however, GC linear allocation isn't
 CPU-cache friendly, meaning that if you get that memory fast, the first
 actions you'll do on that memory will typically be an order of magnitude
 slower than if you had been returned cached memory (particularly
 noticeable for allocations of a few hundreds of kB of temporaries, string
 concatenations, growing arrays, etc.).

1. ever heard of memory prefetch? You can do that explicitly, but most 
current CPU uarchitectures does that implicitly for simple access pattersn 
(and linear walki is one of the simplest).
2. sorry but if you allocate few hundred of KB or more at once it won't be 
cached anyway, regardless of the allocator.
3. temporaries should come from stack anyway.


 Another drawback of linear allocation is interleaving, which often
 reduces the cache efficiency by placing heterogeneous data together
 (depends on the application of course, but it can hit you rather severely
 on some composite data structures).

Sorry, but this goes the opposite way.  Randomly scattered allocations are 
worse than using large compact block. Those, who have to optimise their 
data for cache use know that, and allocate large memory pools and then 
arrange data the way they want. Cache colloring and stuff is easier to do 
when you do not have to deal with stuff scattered everywhere.

This is one of the *advantages* of compacting allocators, that they alocate 
with no internal fragmentation and that after compacting frequently used 
parts are close together, and with just somwehat smart design of compaction 
algorithm things used together are also placed together. This is certainly 
good for cache not bad (it's obvious when you look at typical CPU cache 
algorithm -- this minimises the amount of cache-line conflicts).



   all the cost is in compacting which is linear.

 Compacting might be linear, but it's cache unfriendly, which on a modern
 CPU means an order of magnitude slower memory operations, and that
 happens practically on the whole allocated memory.

Prefetch is your friend. Then GC might be made so that not every collection 
has to hit entire memory. And collection is often incremental (interleaved 
with user code execution).


 If some of it was
 swapped out, you can then expect hell (I've seen it happen), and as
 compaction is a necessity of linear allocation, you can never be 100%
 sure to avoid it with a linearly allocating GC.


Well, I had once wait ~half a minute for 

Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Jan Ruzicka
Enough guys
each camp can make distinct implementation.
Use this forum to discuss an interface.
Let the results speak for themselves.
Lets discuss test code.
Lets discuss benchmark code.
Instead of discussing bunch of what-ifs
let's see how the implementation does.
Is there some wiki[1] where we can collect mentioned ideas?
Jan
[1] (like www.twiki.org or http://c2.com/cgi/wiki)
On Feb 25, 2005, at 13:11, Sebastian Kaliszewski wrote:
On Friday 25 February 2005 17:29, Eric Grange wrote:
1. This is not entirely true (the cost is at best logarithmic on 
the
number of objects or your allocator has terrible fragmentation)
Not really, you can use a memory map and achieve much lower
fragmentation than classic memory managers
1. Memory map brings no quarantees of const time.
2. Same applies to GC managers. BTW GC can use the very same
allocation/deallocation algorithm.
(cf. FastMM submissions
in the FastCode project in the b.p.d.basm borland ng).
In practice, you're memory usage will be a lot lower than that
of a GC.
You're forgetting internal fragmentation. It typical allocator 
allocating
block with power of 2 sizes (4, 8, 16, 32, up to page size or small
multiply of page size) assuming flat size distribution you have ~33%
fragmentation.


2. You have to initialise your allocated data anyway.
That's not a practical issue because:
- initialization may be a task of the user's code, thus doesn't
   fall to the memory manager
But must happen anyway.
- you can use virtual memory facilities and have the initialization
   to zeroes happen automagically, no need to trash the CPU cache
   by explicitly filling with zeroes.
No way. It does not. At best it's delayed up to the point when memory 
gets
used actually rather than being just allocated. But then OS has to 
clear
the page.


3. In real life often you have virtual memory system underneath and
there is no guarantee whatosoever.
The management costs of the VM system are typically negligible
Neglibile but not const (they're mostly linear -- as memory must be 
cleared
before porcess might use it -- due to basic security requirements).

if you
don't enter the realm of disk swapping, at which point the performance
of GC schemes completely collapses during garbage collections
Modern generational GC's are less suspectible to such problems.
and
compactions,
Not every GC is compacting GC.
while a classic allocator can live perfectly happily with
part of its memory swapped out.
GC allocation (in case of compacting collecotr) is constant time
trivially,
Allocation is alway constant time whatever the allocator if you do it
right,
Nope. See above  below.
And even of you artificially restrict yourself to small span of small 
object
sizes yuo have to check quite a bunch of conditions, and conditional
branches are not free. It's allwayes order or two of magnitude slower 
than
adding constant to a heap pointer.


that's not a comparison point, however, GC linear allocation isn't
CPU-cache friendly, meaning that if you get that memory fast, the 
first
actions you'll do on that memory will typically be an order of 
magnitude
slower than if you had been returned cached memory (particularly
noticeable for allocations of a few hundreds of kB of temporaries, 
string
concatenations, growing arrays, etc.).
1. ever heard of memory prefetch? You can do that explicitly, but most
current CPU uarchitectures does that implicitly for simple access 
pattersn
(and linear walki is one of the simplest).
2. sorry but if you allocate few hundred of KB or more at once it 
won't be
cached anyway, regardless of the allocator.
3. temporaries should come from stack anyway.


Another drawback of linear allocation is interleaving, which often
reduces the cache efficiency by placing heterogeneous data together
(depends on the application of course, but it can hit you rather 
severely
on some composite data structures).
Sorry, but this goes the opposite way.  Randomly scattered allocations 
are
worse than using large compact block. Those, who have to optimise their
data for cache use know that, and allocate large memory pools and then
arrange data the way they want. Cache colloring and stuff is easier to 
do
when you do not have to deal with stuff scattered everywhere.

This is one of the *advantages* of compacting allocators, that they 
alocate
with no internal fragmentation and that after compacting frequently 
used
parts are close together, and with just somwehat smart design of 
compaction
algorithm things used together are also placed together. This is 
certainly
good for cache not bad (it's obvious when you look at typical CPU cache
algorithm -- this minimises the amount of cache-line conflicts).



all the cost is in compacting which is linear.
Compacting might be linear, but it's cache unfriendly, which on a 
modern
CPU means an order of magnitude slower memory operations, and that
happens practically on the whole allocated memory.
Prefetch is your friend. Then GC might be made so that not every 

Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Ales Katona
Jan Ruzicka  wrote / napísal (a):
Enough guys
each camp can make distinct implementation.
Use this forum to discuss an interface.
Let the results speak for themselves.
Lets discuss test code.
Lets discuss benchmark code.
Instead of discussing bunch of what-ifs
let's see how the implementation does.
Is there some wiki[1] where we can collect mentioned ideas?
Jan
[1] (like www.twiki.org or http://c2.com/cgi/wiki)
On Feb 25, 2005, at 13:11, Sebastian Kaliszewski wrote:
On Friday 25 February 2005 17:29, Eric Grange wrote:
1. This is not entirely true (the cost is at best logarithmic on the
number of objects or your allocator has terrible fragmentation)

Not really, you can use a memory map and achieve much lower
fragmentation than classic memory managers

1. Memory map brings no quarantees of const time.
2. Same applies to GC managers. BTW GC can use the very same
allocation/deallocation algorithm.
(cf. FastMM submissions
in the FastCode project in the b.p.d.basm borland ng).
In practice, you're memory usage will be a lot lower than that
of a GC.

You're forgetting internal fragmentation. It typical allocator 
allocating
block with power of 2 sizes (4, 8, 16, 32, up to page size or small
multiply of page size) assuming flat size distribution you have ~33%
fragmentation.


2. You have to initialise your allocated data anyway.

That's not a practical issue because:
- initialization may be a task of the user's code, thus doesn't
   fall to the memory manager

But must happen anyway.
- you can use virtual memory facilities and have the initialization
   to zeroes happen automagically, no need to trash the CPU cache
   by explicitly filling with zeroes.

No way. It does not. At best it's delayed up to the point when memory 
gets
used actually rather than being just allocated. But then OS has to clear
the page.


3. In real life often you have virtual memory system underneath and
there is no guarantee whatosoever.

The management costs of the VM system are typically negligible

Neglibile but not const (they're mostly linear -- as memory must be 
cleared
before porcess might use it -- due to basic security requirements).

if you
don't enter the realm of disk swapping, at which point the performance
of GC schemes completely collapses during garbage collections

Modern generational GC's are less suspectible to such problems.
and
compactions,

Not every GC is compacting GC.
while a classic allocator can live perfectly happily with
part of its memory swapped out.
GC allocation (in case of compacting collecotr) is constant time
trivially,

Allocation is alway constant time whatever the allocator if you do it
right,

Nope. See above  below.
And even of you artificially restrict yourself to small span of small 
object
sizes yuo have to check quite a bunch of conditions, and conditional
branches are not free. It's allwayes order or two of magnitude slower 
than
adding constant to a heap pointer.


that's not a comparison point, however, GC linear allocation isn't
CPU-cache friendly, meaning that if you get that memory fast, the first
actions you'll do on that memory will typically be an order of 
magnitude
slower than if you had been returned cached memory (particularly
noticeable for allocations of a few hundreds of kB of temporaries, 
string
concatenations, growing arrays, etc.).

1. ever heard of memory prefetch? You can do that explicitly, but most
current CPU uarchitectures does that implicitly for simple access 
pattersn
(and linear walki is one of the simplest).
2. sorry but if you allocate few hundred of KB or more at once it 
won't be
cached anyway, regardless of the allocator.
3. temporaries should come from stack anyway.


Another drawback of linear allocation is interleaving, which often
reduces the cache efficiency by placing heterogeneous data together
(depends on the application of course, but it can hit you rather 
severely
on some composite data structures).

Sorry, but this goes the opposite way.  Randomly scattered 
allocations are
worse than using large compact block. Those, who have to optimise their
data for cache use know that, and allocate large memory pools and then
arrange data the way they want. Cache colloring and stuff is easier 
to do
when you do not have to deal with stuff scattered everywhere.

This is one of the *advantages* of compacting allocators, that they 
alocate
with no internal fragmentation and that after compacting frequently used
parts are close together, and with just somwehat smart design of 
compaction
algorithm things used together are also placed together. This is 
certainly
good for cache not bad (it's obvious when you look at typical CPU cache
algorithm -- this minimises the amount of cache-line conflicts).



all the cost is in compacting which is linear.

Compacting might be linear, but it's cache unfriendly, which on a 
modern
CPU means an order of magnitude slower memory operations, and that
happens practically on the whole allocated memory.

Prefetch is your friend. 

Re: [fpc-devel] Modernising Pascal

2005-02-25 Thread Florian Klaempfl
Jan Ruzicka wrote:
Is there some wiki[1] where we can collect mentioned ideas?
http://www.freepascal.org/wiki
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-24 Thread Jamie McCracken
DrDiettrich wrote:
My main gripes with Delphi/pascal is its additional verbosity and
somewhat tedious coding practices which seem superfluous in some cases.
Now I dont mind typing a bit extra to make code cleaner and more legible
but I have a few ideas which would reduce needless typing and improve
clarity at the same time.

IMO the best solution for (almost) all of your problems were garbage
collection. GC is part of Oberon, and it would fit into .NET/DotGNU as
well.

GC is very inefficient with memory and current implementations tend to 
cost a lot performance wise too.

GC gets a lot slower with the more objects you create.
Mixing unmanaged with managed code cause severe performance issues 
(marshalling penalties calling ummanaged c functions)

Interoperability with C gets increasingly difficult. Writing bindings 
becomes much more complicated and time consuming.

GC is therefore a poor choice for a high performance language IMHO.


1. Memory management. Delphi is quite incosistent here by allowing
component classes to be auto managed (via their owner) whilst
non-component class have to be manually managed.

In a GUI a management overhead is acceptable, in other classes IMO it's
not a good idea: the management costs time and requires rigid design
rules, what makes it not very convenient and safe to use.

no longer be a need for having loads of try..finally statements

GC ;-)
It might be better to do this in an IDE and get it to add the 
try..finally crap.

EG if I say use the @ symbol to indicate a variable should be auto 
created and destroyed then I could have :

var st@, st2@ : tstringlist;
begin
  st.add('some text');
  st2.add('some more text');
end;
which the IDE would translate behind the scenes to :
var st, st2 : tstringlist;
begin
   st := tstringlist.create;
   try
 st2 :=  tstringlist.create;
 try
   st .add('some text');
   st2.add('some more text');
finally
  st2.free;
end;
  finally
st.free;
  end;
end;
I do need an IDE anyhow for container based GTK2/Gnome2/Glade apps so 
maybe I ought to start writing one that implements this.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-24 Thread Michael Van Canneyt

On Thu, 24 Feb 2005, Jamie McCracken wrote:
It might be better to do this in an IDE and get it to add the try..finally 
crap.

EG if I say use the @ symbol to indicate a variable should be auto created 
and destroyed then I could have :

var st@, st2@ : tstringlist;
begin
 st.add('some text');
 st2.add('some more text');
end;
which the IDE would translate behind the scenes to :
var st, st2 : tstringlist;
begin
  st := tstringlist.create;
  try
st2 :=  tstringlist.create;
try
  st .add('some text');
  st2.add('some more text');
   finally
 st2.free;
   end;
 finally
   st.free;
 end;
end;
I do need an IDE anyhow for container based GTK2/Gnome2/Glade apps so maybe I 
ought to start writing one that implements this.
Why don't you see if you can get this implemented as an add-on in
Lazarus ? You get the rest of the IDE for free.
Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-24 Thread Jonas Maebe
On 24 feb 2005, at 13:51, Jamie McCracken wrote:
IMO the best solution for (almost) all of your problems were garbage
collection. GC is part of Oberon, and it would fit into .NET/DotGNU as
well.
GC is very inefficient with memory and current implementations tend to 
cost a lot performance wise too.
It's *much* faster than reference counting everything. Reference 
counting is more or less the slowest garbage collection technique there 
is (except if only very few objects have to garbage collected). It also 
can't deal with circular references.

GC gets a lot slower with the more objects you create.
Reference counting too.
Mixing unmanaged with managed code cause severe performance issues 
(marshalling penalties calling ummanaged c functions)

Interoperability with C gets increasingly difficult. Writing bindings 
becomes much more complicated and time consuming.
You get the same problem if you pass a reference counted structure to C 
(or any other language).

Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-24 Thread Jamie McCracken

I do need an IDE anyhow for container based GTK2/Gnome2/Glade apps so 
maybe I ought to start writing one that implements this.

Why don't you see if you can get this implemented as an add-on in
Lazarus ? You get the rest of the IDE for free.
In the short term yes (although I use delphi 5 under Wine for editing 
stuff - its nicer on my eyes than GTK1) but long term I would love to 
have a GTK2 IDE integrated with Glade3 for writing HIG compliant apps as 
I do all my UI stuff using Glade.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-24 Thread Jamie McCracken
Jonas Maebe wrote:
On 24 feb 2005, at 13:51, Jamie McCracken wrote:
IMO the best solution for (almost) all of your problems were garbage
collection. GC is part of Oberon, and it would fit into .NET/DotGNU as
well.

GC is very inefficient with memory and current implementations tend to 
cost a lot performance wise too.

It's *much* faster than reference counting everything. Reference 
counting is more or less the slowest garbage collection technique there 
is (except if only very few objects have to garbage collected). It also 
can't deal with circular references.
Thats why I would want ref count for Tobjects and not Tcomponents. 
Partial ref counting should be faster than doing GC on everything.


GC gets a lot slower with the more objects you create.

Reference counting too.
GC is worse here because the pointers are not static in GC so 
referencing an object means looking up the actual address in a lookup 
list (so more overhead whenever you call a method or pass an object 
reference). GC does not use the stack efficiently and has to use a lot 
of heap so its extremely inefficient. Ever see GC compact swap?


Mixing unmanaged with managed code cause severe performance issues 
(marshalling penalties calling ummanaged c functions)

Interoperability with C gets increasingly difficult. Writing bindings 
becomes much more complicated and time consuming.

You get the same problem if you pass a reference counted structure to C 
(or any other language).
yes but with GC everything would have to be managed whilst just ref 
counting Tobject would not cause these problems (you cant access a 
tobject from C anyhow). Tobject is the only weak point in Delphi's 
memory management so I would say using GC to correct that would be overkill.

jamie.

Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Jamie McCracken
Marco van de Voort wrote:

The best solution I can 
think for this is to reference count non-component classes. This should 
be safe for TObjects but obviously not for Tcomponent descendants (cf 
circular reference problem) so a protected variable could be added to 
TObject to specify whether to ref count it or not (with TComponent 
turning it off).

This is impossible. 90% of the language wouldn't work anymore as it does
now, and besides, it would be dog slow. Could be that it gets slower than
Boehm GC even.

Thats very pessimistic!
Why wouldn't existing code work with this? If you call free on an object 
it would ignore the ref count and free it - so it wont alter how 
existing code works so it certainly should not break anything. You can 
always create a new dialect that has this if you're worried about 
existing code (I take it most of the existing code is using FPC mode 
dialect).

Is'nt the overhead for reference counting negligible compared to having 
try..finally blocks which the programmer would have to add anyway if we 
didn't refcount them?

(there also pointers for cases where you dont need try..finally)
This will improve legibility of code too as there will no longer be a need
for having loads of try..finally statements to free stuff.


How do you free objects then? Those try..finally's are there actually because
of the refcounting.
The system frees them automatically - there no need to manually add 
try..finally statements. The benefit is clearer code and less chance of 
a memory leak.


2. For Each. Its in Delphi 2005 and every modern language implements it.

Yeah, and I still wonder why. There is nothing to gain with it. 
one less variable to manually declare
 

3. Increasing the number of base types to include common stuff like 
lists (Tlist, TStringList). Python does this nicely and theres no reason 
Pascal cant.

I partially agree with you that the container types of Delphi aren't the
strongest point. However the solution is to make a lib with better types.
Pulling it in the compiler with ref counting however is something totally
else, and will make them dog slow.
Keep in mind that I can walk through 5-6 million (real world) objects in
just under 2 secs in Pascal/Delphi on an already old 2GHz P IV, and inspect
them all. Try that in Python.
I know python is dog slow and its far from perfect but it does have 
clearer and more compact code than pascal as a result of ref counting 
stuff and improving the base container types.

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Florian Klaempfl
Jamie McCracken wrote:
Marco van de Voort wrote:

The best solution I can think for this is to reference count 
non-component classes. This should be safe for TObjects but obviously 
not for Tcomponent descendants (cf circular reference problem) so a 
protected variable could be added to TObject to specify whether to 
ref count it or not (with TComponent turning it off).

This is impossible. 90% of the language wouldn't work anymore as it does
now, and besides, it would be dog slow. Could be that it gets slower than
Boehm GC even.

Thats very pessimistic!
Why wouldn't existing code work with this? If you call free on an object 
it would ignore the ref count and free it - so it wont alter how 
existing code works so it certainly should not break anything. You can 
always create a new dialect that has this if you're worried about 
existing code (I take it most of the existing code is using FPC mode 
dialect).

Is'nt the overhead for reference counting negligible compared to having 
try..finally blocks which the programmer would have to add anyway if we 
didn't refcount them?

(there also pointers for cases where you dont need try..finally)

Ref. counting creates an huge amount of implicit try .. finally blocks which 
have a heavy impact on speed.

Consider
function f1(myobject : tobject) : tobject;
  begin
  end;
function f2(myobject : iunknown) : iunknown;
  begin
  end;
var
  o : tobject;
  i : iunknown;
begin
  f1(o);
  f2(i);
end.
lets have a look at the ouput (IUnknown is ref. counted):
# [2] begin
.globl  P$PROGRAM_F1$TOBJECT$$TOBJECT
P$PROGRAM_F1$TOBJECT$$TOBJECT:
# Temps allocated between ebp+0 and ebp+0
pushl   %ebp
movl%esp,%ebp
# Var myobject located in register
# Var $result located in register
movl%eax,%edx
# [3] result:=myobject;
movl%edx,%ecx
# [4] end;
movl%ecx,%eax
leave
ret
.section .text
.balign 4
.balign 4
# [7] begin
.globl  P$PROGRAM_F2$IUNKNOWN$$IUNKNOWN
P$PROGRAM_F2$IUNKNOWN$$IUNKNOWN:
# Temps allocated between ebp-48 and ebp-4
pushl   %ebp
movl%esp,%ebp
subl$48,%esp
movl%ebx,-48(%ebp)
# Var myobject located in register
# Var $result located at ebp-4
movl%eax,%ebx
movl$0,-4(%ebp)
leal-16(%ebp),%eax
movl%eax,%ecx
leal-40(%ebp),%eax
movl%eax,%edx
movl$1,%eax
callFPC_PUSHEXCEPTADDR
callFPC_SETJMP
pushl   %eax
testl   %eax,%eax
jne .L15
# [8] result:=myobject;
movl%ebx,%edx
leal-4(%ebp),%eax
callfpc_intf_assign
.L15:
callFPC_POPADDRSTACK
popl%eax
testl   %eax,%eax
je  .L16
# [9] end;
movl$INIT__SYSTEM_IUNKNOWN,%edx
leal-4(%ebp),%eax
callfpc_finalize
callFPC_RERAISE
.L16:
movl-4(%ebp),%eax
movl-48(%ebp),%ebx
leave
ret
[...]
# [16] f1(o);
movl%esi,%eax
callP$PROGRAM_F1$TOBJECT$$TOBJECT
# [17] f2(i);
leal-44(%ebp),%edx
movl%edx,%eax
callFPC_INTF_DECR_REF
movl%ebx,%eax
callP$PROGRAM_F2$IUNKNOWN$$IUNKNOWN
movl%eax,-44(%ebp)
leal-44(%ebp),%edx
movl%edx,%eax
callFPC_INTF_DECR_REF
movl$0,-44(%ebp)

So if you look at this, you know why classes aren't ref. counted. And there is 
no chance to avoid the code generated for the interface.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Marco van de Voort
 Marco van de Voort wrote:
 
  
 The best solution I can 
 think for this is to reference count non-component classes. This should 
 be safe for TObjects but obviously not for Tcomponent descendants (cf 
 circular reference problem) so a protected variable could be added to 
 TObject to specify whether to ref count it or not (with TComponent 
 turning it off).
  
  
  This is impossible. 90% of the language wouldn't work anymore as it does
  now, and besides, it would be dog slow. Could be that it gets slower than
  Boehm GC even.
 
 Thats very pessimistic!

No, that is reading literature.
 
 Why wouldn't existing code work with this? 
 If you call free on an object 
 it would ignore the ref count and free it

That messes up the ref counts. Make some sample code that throws some objects
to different procs and keep track of ref counts.

 Is'nt the overhead for reference counting negligible compared to having 
 try..finally blocks which the programmer would have to add anyway if we 
 didn't refcount them?

 (there also pointers for cases where you dont need try..finally)

Which one?
 
  How do you free objects then? Those try..finally's are there actually 
  because
  of the refcounting.
  
 
 The system frees them automatically - there no need to manually add 
 try..finally statements. The benefit is clearer code and less chance of 
 a memory leak.

Which system? The ref counting system pretty much _is_ the try finally :)

 2. For Each. Its in Delphi 2005 and every modern language implements it.
  
  
  Yeah, and I still wonder why. There is nothing to gain with it. 
 
 one less variable to manually declare

Implement something in lazarus that auto-adds the variable to the local var
section. No need for language extensions.

D2005 reasons for it lie in the .NET, but those don't apply to the non .NET 
world.
(yes it works in d2005/win32 too, but it is useless there)

  I partially agree with you that the container types of Delphi aren't the
  strongest point. However the solution is to make a lib with better types.
  
  Pulling it in the compiler with ref counting however is something totally
  else, and will make them dog slow.
  
  Keep in mind that I can walk through 5-6 million (real world) objects in
  just under 2 secs in Pascal/Delphi on an already old 2GHz P IV, and inspect
  them all. Try that in Python.
 
 I know python is dog slow and its far from perfect but it does have 
 clearer and more compact code than pascal as a result of ref counting 
 stuff and improving the base container types.

I do not agree. /me thinks Python looks messy.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Jamie McCracken
Marco van de Voort wrote:


2. For Each. Its in Delphi 2005 and every modern language implements it.

Yeah, and I still wonder why. There is nothing to gain with it. 
one less variable to manually declare

Implement something in lazarus that auto-adds the variable to the local var
section. No need for language extensions.
My mistake it actually avoids initialising the loop variable rather than 
not declaring it:

for i in myarray do
  myarray[i] := 0;
as opposed to
for i := low(myarray) to high (myarray) do
   myarray[i] := 0;
I think the for..in is much clearer and more compact (it works for sets, 
arrays and other enumerated types)

jamie.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Jonas Maebe
On 23 feb 2005, at 14:04, Jamie McCracken wrote:
My mistake it actually avoids initialising the loop variable rather 
than not declaring it:

for i in myarray do
  myarray[i] := 0;
as opposed to
for i := low(myarray) to high (myarray) do
   myarray[i] := 0;
I think the for..in is much clearer and more compact (it works for 
sets, arrays and other enumerated types)
I'm not sure whether it's that clear. In case of a set, I agree, but 
for an array it would seem more logical to me if i iterated over all 
values in the array, not over all indexes.

Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Marco van de Voort
 My mistake it actually avoids initialising the loop variable rather than 
 not declaring it:
 
 for i in myarray do
myarray[i] := 0;
 
 as opposed to
 
 for i := low(myarray) to high (myarray) do
 myarray[i] := 0;
 
 
 I think the for..in is much clearer and more compact (it works for sets, 
 arrays and other enumerated types)

The constructs are not that frequent, so typing is not limited. I do not agree 
on
the clearer part also.

From low to high is more clear than IN, since that says nothing about order.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-23 Thread Mattias Gaertner
On Wed, 23 Feb 2005 13:45:51 +0100 (CET)
[EMAIL PROTECTED] (Marco van de Voort) wrote:

  one less variable to manually declare
 
 Implement something in lazarus that auto-adds the variable to the
 local var section. 

It already exists. Example:

i:=0;

Place cursor on i and press Code Completion (Ctrl+Shift+C) and it will
add var i: integer;.


Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


RE: [fpc-devel] Modernising Pascal

2005-02-22 Thread Jose Manuel

 (note I did not use a T in front of StringList so as to distinguish it 
 from non-base types and also to maintain backwards compatibility with 
 existing code that uses TStringList conventionally)
 
 
 jamie.

Are you always drunk?


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-22 Thread Florian Klaempfl
Jamie McCracken wrote:
Hi,
Just wandering if any of you are interested in modernising Pascal which 
is looking quite dated when compared to modern languages like Python. 
Oh, the language which is on fortran 77 level regarding formatting? 
Sorry, couldn't resist :)

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


RE: [fpc-devel] Modernising Pascal

2005-02-22 Thread peter green

 1. Memory management. Delphi is quite incosistent here by allowing
 component classes to be auto managed (via their owner) whilst
 non-component class have to be manually managed. The best solution I can
 think for this is to reference count non-component classes. This should
 be safe for TObjects but obviously not for Tcomponent descendants (cf
 circular reference problem) so a protected variable could be added to
 TObject to specify whether to ref count it or not (with TComponent
 turning it off). This will improve legibility of code too as there will
 no longer be a need for having loads of try..finally statements to free
 stuff. Backwards compatibility should not be affected so if you call a
 free method it will free it whatever its ref count.
there would be quite some performance penalty to this. Refcounting is
actually quite expensive especially because of the way it adds loads of
extra try-finally blocks to the asm.

furthermore how do you propose to do such a thing while maintaining the
capability to typecast safely back and forward between object types and
integer types which so much code relys on.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Modernising Pascal

2005-02-22 Thread Jamie McCracken
peter green wrote:
1. Memory management. Delphi is quite incosistent here by allowing
component classes to be auto managed (via their owner) whilst
non-component class have to be manually managed. The best solution I can
think for this is to reference count non-component classes. This should
be safe for TObjects but obviously not for Tcomponent descendants (cf
circular reference problem) so a protected variable could be added to
TObject to specify whether to ref count it or not (with TComponent
turning it off). This will improve legibility of code too as there will
no longer be a need for having loads of try..finally statements to free
stuff. Backwards compatibility should not be affected so if you call a
free method it will free it whatever its ref count.
there would be quite some performance penalty to this. Refcounting is
actually quite expensive especially because of the way it adds loads of
extra try-finally blocks to the asm.
not much more cause you would still need try finally blocks in most 
cases for robust code. In other cases you can use a pointer to avoid 
overhead (IE in cases where you are not actually creating instances).

furthermore how do you propose to do such a thing while maintaining the
capability to typecast safely back and forward between object types and
integer types which so much code relys on.
not sure I understand the problem here.  Can you give an example?
jamie.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel