[M3devel] optimization [ was Re: Performance issues with CM3 ]

Mika Nystrom mika at async.caltech.edu
Mon Apr 27 04:59:32 CEST 2009


Ah, yeah... I have to admit it does.

Whenever it pushes the stack in Scheme it makes a TRY block so it
can print a pretty traceback if anything goes wrong... if something
goes wrong deep into a call it prints an error message for every
frame in Scheme (not tail calls obviously, see Hendrik's question),
concatenating them as it pops out of the frames, until you're back
at the REPL.

Example:

> (define (add1 x) ( + x 1))
add1
> (define (x) (map add1 '(1 2 3 junk)))
x
> (x)
EXCEPTION! expected a double, got: junk
(called from) eval (+ x 1)   
(called from) eval (x)
> 

Hmm.. so if I disable tracebacks my code should get a lot faster.

> (time-call (lambda()(make-standard-stuff "Example")))
1.3191220290027559
> (toggle-tracebacks)
#f
> (time-call (lambda()(make-standard-stuff "Example")))
1.1270759491017088
>

Neat... sort of.  17% speedup is nothing to sneeze at, but I do like
those tracebacks, too.

    Mika



Tony Hosking writes:
>I was just wondering if your code has a lot of TRY blocks, which come  
>with the PushEFrame overhead.
>
>On 27 Apr 2009, at 12:28, Mika Nystrom wrote:
>
>> How would I know?  I'm trying to turn on profiling but it seems to  
>> be a
>> bit involved.  Involves re-building all the libraries?
>>
>> (cm3 -profile seems to look for FreeBSD4p instead of plain  
>> FreeBSD4...)
>>
>>     Mika
>>
>> Tony Hosking writes:
>>> Hmm.  Interesting.  What about exception scopes?
>>>
>>> On 27 Apr 2009, at 11:17, Mika Nystrom wrote:
>>>
>>>> Tony Hosking writes:
>>>> ...
>>>>>> With lots of tweaks and adjustments, I now see my code running  
>>>>>> about
>>>>>> 100% slower under CM3 than the same code does under PM3 (on the
>>>>>> same machine).  This is including my typecase hacks, as described
>>>>>> earlier today.  I'm guessing most of it is the FreeBSD pthreads
>>>>>> implementation in libc_r + the calls to PushEFrame.
>>>>>
>>>> Yikes!  How much of this is module initialization (startup) time?
>>>>>
>>>>
>>>> Ok, I re-checked just to make sure.  As far as I know, exactly the
>>>> same code,
>>>> no initialization overhead (program's already running):
>>>>
>>>> CM3:
>>>>
>>>>> (time-call (lambda()(make-standard-stuff "Example")))
>>>> 1.309586018207483
>>>>>
>>>>
>>>> PM3:
>>>>
>>>>> (time-call (lambda()(make-standard-stuff "Example")))
>>>> 0.5641579627990723
>>>>>
>>>>
>>>> Bear in mind this is pretty close to a worst-case test for the
>>>> "delta" between
>>>> PM3 and CM3.  Lots of small procedures, lots of typecases.
>>>>
>>>> Well, actually, I can make it worse.  Turn on locking in the Scheme
>>>> environments
>>>> (so that they could be used by multi-threaded interpreters):
>>>>
>>>> CM3:
>>>>
>>>>> (time-call (lambda()(make-standard-stuff "Example")))
>>>> 2.1610950572649017
>>>>>
>>>>
>>>> PM3:
>>>>
>>>>> (time-call (lambda()(make-standard-stuff "Example")))
>>>> 0.6010241508483887
>>>>>
>>>>
>>>> CM3 without my change to RTType:
>>>>
>>>>> (time-call (lambda()(make-standard-stuff "Example")))
>>>> 2.2972461158642545
>>>>>
>>>>
>>>> 250% slower.
>>>>
>>>> But it is very demanding on pthreads.  Lots of little procedures,
>>>> lots of typecases, lots of locking.  (No contention, though.)
>>>>
>>>>   Mika
>>>>
>>>> P.S. the code in question is a scheme-m3 stub generator; it's making
>>>> stub interfaces in the tests above.
>>>
>



More information about the M3devel mailing list