>>>> "MS" == Michael Sperber
<sperber(a)informatik.uni-tuebingen.de> writes:
>>>> "Martin" == Martin Buchholz
<martin(a)xemacs.org> writes:
Martin> A few points:
Martin> - it seems unfair to test the performance of code that hasn't been
Martin> byte-compiled.
MS> Well, it's just an example for the really serious problem:
MS> *Everything* has gotten noticeably slower. What I'm saying is: it
MS> didn't use to be this way. Something has changed. The GC algorithm
MS> doesn't explain the problem. It's not the GC which has gotten slower,
MS> it's the computation between GCs.
It's certainly possible that our lisp allocation bookkeeping is
somehow broken. However...
It is clear that the cost of one gc should be proportional to the
amount of lisp storage allocated. If many elisp libraries are loaded,
then there will be more lisp storage in the form of bytecode
functions. But if a huge amount of lisp storage is allocated and
subsequently freed, gc should not be much slower afterwards.
I'm willing to help fix gc allocation problems.
Olivier has nuked purespace, which was our previous extremely
primitive kludgy form of generational gc. But we haven't replaced it
with anything. As a result, although mark_object is significantly
faster than 21.1, garbage-collect() as a whole is 30% slower. I
assume Olivier is aware of the effect of his actions, and that part of
his job with the recent lisp engine changes is to reintroduce
generational garbage collection in some form.
A lot of performance work can go into making less lisp allocation, and
making gc'ing the allocated lisp faster:
- Lisp_Compiled functions should not have bytecode instructions as a
separate lisp object, but instead as simple xmalloc'ed memory. This
will eliminate (number of bytecode functions) lisp objects.
Similarily, the constants vector can be made part of the compiled
function object itself, as a flexible array, with the same win
(these will also make funcalls a little faster).
- lazy bytecode loading should be reimplemented. It was turned off a
few years ago because it didn't work with Mule. This is a really
big memory-saving optimization.
- etc..
But generational gc is the most important thing.
Martin> Make a write barrier for all lisp object types. (Hmmm, will make setq
Martin> and let slow until lexical variables are implemented)
Martin> Add a generation field to lrecords (perhaps just two generations - the
Martin> buzzword is "object nursery").
Martin> keep track of pointers from old generations to new.
Martin> Easy, right?
MS> :-) Also, we really want a moving GC, so we need more GCPRO information.
Unclear. It is _traditionally_ thought that a compacting collector
wins. For a dissenting opinion, read
http://www.hpl.hp.com/personal/Hans_Boehm/gc/complexity.html
Practically, I think it's too difficult to do a moving collector for
XEmacs. Too many gc bugs to track down! You are welcome to prove me
wrong, but be prepared to fix all the gc bugs yourself.