develooper Front page | perl.perl6.internals | Postings from August 2002

Reducing DOD runs by manual header freeing

Thread Next
Mike Lambert
August 24, 2002 00:09
Reducing DOD runs by manual header freeing
Message ID:
From an earlier message about how many dod runs were being performed...

> >Currently, 5000 iterations of life execute in 6 seconds, with 42K DOD
> >runs. At that rate, we have a rollover every week. Not really a problem,
> >but if we have code which doesn't allow for rollover, it is a problem.
> That feels like we're doing far too many DOD runs there, but that's a
> tuning issue.

Well, in the particular case of life.pasm, I decided to look into why
there are so many DOD runs. collection runs are down quite a lot due to
our use of COW, but we're still chewing through headers.

Turns out we perform this sequence of opcodes maybe 9 million times:
	substr S0, S15, I3, 1
	ne S0, "*", North
which generates a new COW header to hold the substring.

If I introduce a 'free' opcode which frees the header, I can improve
life.pbc performance from 6.30 seconds to 5.85 seconds, or a speedup of
only 7%.

The results for this "improved" life.pasm give:
5000 generations in 5.859001 seconds. 853.387781 generations/sec
A total of 774596 bytes were allocated
A total of 0 DOD runs were made
A total of 45 collection runs were made
Copying a total of 873412 bytes

So for a case like life.pasm, the 42923 DOD runs it was performing before
were not the major cause of slowdown (yay!). This is likely because:

a) no use of PMCs, and no use of mark_used

b) all headers, which have no depth to their contents

c) a max of 1024 headers, of which only 3 non-constant ones are live at
any given time. So it can reclaim a lot each time.

d) the entire set of 1024 headers was maybe 36K, which easily fits
entirely in the inner-most cpu cache.

e) performing a profile on 'parrot life.pbc' shows most of the time being
spend in 'ne' and 'mod'. I suspect we're becoming mops-bound with
life.pasm. And the overhead of string comparison to perform single-char
comparisons is overkill.

So oh well, I choose a particularly bad example to demonstrate my point.

However, I suspect the above optimization will be useful in more
real-world scenarios with more header usage. Choosing such an example
will be hard to test because it requires manual placement of these
'free' opcodes.

It will, however, require that compilers determine which variables are
able to escape their scope, either by being passed into functions, or
passed out of, and avoid freeing those headers. The register liveness
stuff that IMCC is doing would be a prime example of code that should be
able to do this, I think.

Is this something we can reliably ensure? If so, is it safe to add
'free'-style ops to core.ops to ensure that compilers are able to manage
their headers better when they know how?

Freeing a header prematurely would be a bug, and if run with GC_DEBUG,
would be caught with the new code that Steve Fink contributed, since it
would be detected by a later DOD run as an example of the dead coming back
to life. But people can introduce bugs into their pasm code in many ways.
Should we be offering yet another with the ability to free headers?

Mike Lambert

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About