Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-12 Thread Leopold Toetsch
Jonathan Sillito [EMAIL PROTECTED] wrote:

 Here is another suggestion (I think I mentioned this in another email) we
 could support a few different types of continuations. The simplest
 continuation could be just a saved return address (i.e. an opcode_t*).

I'm fine with that, if its additionally to the current invoke/ret scheme.

 One more thing Leo (excuse my ignorance) why is there a stack calling
 convention in imcc? How does it relate to calling subs via the calling
 convention?

First one sentence from pdd03:

   Please note that the following conventions are only
   necessary when exposing subs and methods via the generic
   parrot routine exposure mechanism.

Parrot calling conventions are for subs and methods which ought to be
accessible like e.g. library functions. All internal language stuff may
use whatever subroutine calling convention that is appropriate.

So there are different ways to call a subroutine:
- stack calling conventions (callee saves used by BASIC, P6C)
- invoke/ret (callee saves used by P6Cs exceptions and rx rules)
- above schemes, caller saves

IMHO the continuation passing scheme can only be additionally to current
schemes.

 Jonathan Sillito

leo


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-12 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Jonathan Sillito [EMAIL PROTECTED] wrote:

 Here is another suggestion (I think I mentioned this in another email) we
 could support a few different types of continuations. The simplest
 continuation could be just a saved return address (i.e. an opcode_t*).

 I'm fine with that, if its additionally to the current invoke/ret scheme.

 One more thing Leo (excuse my ignorance) why is there a stack calling
 convention in imcc? How does it relate to calling subs via the calling
 convention?

 First one sentence from pdd03:

Please note that the following conventions are only
necessary when exposing subs and methods via the generic
parrot routine exposure mechanism.

 Parrot calling conventions are for subs and methods which ought to be
 accessible like e.g. library functions. All internal language stuff may
 use whatever subroutine calling convention that is appropriate.

 So there are different ways to call a subroutine:
 - stack calling conventions (callee saves used by BASIC, P6C)

The eventual Perl 6 implementation should almost certainly move over
to a continuation passing style. 

-- 
Piers


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Leopold Toetsch
Jonathan Sillito [EMAIL PROTECTED] wrote:

 This patch converts parrot to a continuation passing style.

You seem to be changing current tests WRT invoke - does invoke still
work as it did? Or more specifically: Do imcc tests and perl6 test still
pass?

 I am not satisfied with the time taken to make a call. I did some rough
 benchmarking and the parrot implementation makes us slower than python
 2.2.1.

Optimized parrot build?

 $ perl assemble.pl test.pasm test.pbc ; time ./parrot  test.pbc

CGP or jit should be a lot faster.

Some minor remarks:
- the changes s/interp/interpreter/ make it harder the read the real
  changes - and I don't see any benefit to rename variable names.
- you are undoing some PMC_data changes.

leo


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Jerome Vouillon
On Tue, Jun 10, 2003 at 04:59:50PM -0700, Robert Spier wrote:
   mistral-jerome:/tmp  time python test.py
   python test.py  2,59s user 0,00s system 100% cpu 2,582 total
   mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
   ./tst  0,14s user 0,00s system 106% cpu 0,131 total
   mistral-jerome:/tmp  cat test.ml
   let foo () = () in
   for i = 1 to 100 do foo () done
  
  That is impressive. I don't know Ocaml but do you think there is an
  optimization being done since foo takes no args, returns not values and has
  an empty body?
 
 This also isn't a fair comparison.

Here are the results when doing ten times more iterations :

mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
./tst  1,30s user 0,00s system 101% cpu 1,279 total
mistral-jerome:/tmp  time python -O test.py
python -O test.py  22,59s user 0,00s system 98% cpu 23,032 total

 python is compiling test.py to bytecode during the 'time' call.
 
 ocaml is explicitly compiling _to a raw executable_ (and optimizing at
 three different levels) outside the call.  There's no startup overhead
 for the binary.

The startup overhead seems to be rather low.

Precompiled Python code :
mistral-jerome:/tmp  python -O -c \
  import sys,py_compile;py_compile.compile(sys.argv[1],sys.argv[2]) \
  test.py test.pyc
mistral-jerome:/tmp  time python test.pyc
python test.pyc  22,93s user 0,00s system 100% cpu 22,926 total

On-the-fly compilation of the ocaml code :
mistral-jerome:/tmp  time ocaml test.ml
ocaml test.ml  1,33s user 0,01s system 100% cpu 1,336 total

 Also, (in general) for this kind of test you really need to run each a
 lot of times and average.  There's too many things going on on a
 typical system that could tweak things.

I ran the tests several times, and always got similar results.

-- Jerome


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Jerome Vouillon
On Tue, Jun 10, 2003 at 04:00:07PM -0700, Jonathan Sillito wrote:
  -Original Message-
  From: Jerome Vouillon [mailto:[EMAIL PROTECTED]
 
  The python interpreter seems rather slow.  I get these numbers with the
  Ocaml bytecode interpreter.
 
  mistral-jerome:/tmp  time python test.py
  python test.py  2,59s user 0,00s system 100% cpu 2,582 total
  mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
  ./tst  0,14s user 0,00s system 106% cpu 0,131 total
  mistral-jerome:/tmp  cat test.ml
  let foo () = () in
  for i = 1 to 100 do foo () done
 
 That is impressive. I don't know Ocaml but do you think there is an
 optimization being done since foo takes no args, returns not values and has
 an empty body?

No, the bytecode compiler is not performing any optimization in this
case.  Here is the bytecode produced (the Ocaml virtual machine has an
accumulator and a stack).

-- Jerome

 0  BRANCH 5  Jump to offset 5 (skip the function
  body).

   Function foo :
 2  CONST0Store 0 in the accumulator (this is
  the function result).
 3  RETURN 1  Pop one element (the function argument).
  and return.

 5  CLOSURE 0, 2  Build the foo function closure
  (empty environment, code at offset 2).

   Initialisation of the loop :
 8  PUSHCONST1Push the closure on the stack.
  and store 1 (the loop counter) in the
  accumulator.
 9  PUSHCONSTINT 1000 Push the value of the accumulator.
  and store 1000 in the accumulator.
11  PUSH  Push the value of the accumulator.
12  BRANCH 23 Jump to offset 23.

  The loop :
14  CHECK_SIGNALS Check whether there is any pending
  signal (Control-C, for instance)
15  CONST0Store 0 in the accumulator
  (the function parameter).
16  PUSHACC3  Push the value of the accumulator
  and access the 4th element of the
  stack (the function closure).
17  APPLY1Apply the function to its arguments.
18  ACC1  Store the 2nd element of the stack
  (the loop counter) in the accumulator.
19  OFFSETINT 1   Increment the loop counter.
21  ASSIGN 1  Store the value of the loop counter
  back in the stack.
23  ACC0  Store the content of the top of the
  stack (1000) in the accumulator.
24  PUSHACC2  Push the value of the accumulator
  and store the 3rd element of the
  stack (the loop counter) in the
  accumulator.
25  LEINT Compare the accumulator and the top
  of the stack. The top of the stack
  is popped and the result is stored
  in the accumulator.
26  BRANCHIF 14   If the result is true, then jump to
  offset 14.

  Clean-up after the loop :
28  CONST0Put 0 in the accumulator (return
  value of the loop)
29  POP 3 Pop all three elements of the stack


RE: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Jonathan Sillito
 -Original Message-
 From: Leopold Toetsch [mailto:[EMAIL PROTECTED]

 Jonathan Sillito [EMAIL PROTECTED] wrote:

  This patch converts parrot to a continuation passing style.

 You seem to be changing current tests WRT invoke - does invoke still
 work as it did? Or more specifically: Do imcc tests and perl6 test still
 pass?

Not quite. In the case of sub.pmc the 'next' argument to the invoke vtable
function is ignored, instead the continuation to return to is expected to be
in P1. All of what used to be just plain 'invoke' now should be
'invokecc' -- this will do the extra setup. So in the normal cases we should
use:

invokecc # rather than invoke
invoke P1# rather than ret

All imcc tests pass if the attached tiny patch is applied. Perl6 on the
other hand I have never looked at, but I can do that next I guess ...

Oh, one other difference is that 'invoke Px' will now put the sub from Px
into P0, since this is where the callee will expect it to be. Or is this
form of the op intended for something else?

  I am not satisfied with the time taken to make a call. I did some rough
  benchmarking and the parrot implementation makes us slower than python
  2.2.1.

 Optimized parrot build?

  $ perl assemble.pl test.pasm test.pbc ; time ./parrot  test.pbc

 CGP or jit should be a lot faster.

Adding --jit does not seem to make a difference. Am I missing somthing?

 Some minor remarks:
 - the changes s/interp/interpreter/ make it harder the read the real
   changes - and I don't see any benefit to rename variable names.

This was for consistency since everywhere else 'interpreter' seems to be
used.

 - you are undoing some PMC_data changes.

Doh!

--
Jonathan Sillito


imcc.patch
Description: Binary data


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Jonathan Sillito
On Wed, 11 Jun 2003, Leopold Toetsch wrote:

 Jonathan Sillito wrote:
 
 Why not just leave the old behaviour?
 IMHO[1]:
 - Make a new class based on Continuations
 - invokecc and such are based on it

[snip]

 [1] I don't know too much about all the HL stuff. But anyway, some 
 languages might be quite fine with the current implementation (which 
 seems to be more lightweight, when it just comes to calling a plain 
 subroutine) Have a look at P6Cs usage for exceptions and in regexen 
 code. I know, its not final, but its a working implementation. Some less 
 fancy HL might be just fine with the way how its working currently.
 
 Or I'm totally wrong here ;-)

Here is another suggestion (I think I mentioned this in another email) we 
could support a few different types of continuations. The simplest 
continuation could be just a saved return address (i.e. an opcode_t*). 
This would be roughly as lightweight as the current implementation, I 
think. What do you think? I am thinking it would be easier to have one 
calling convention then callees know what to expect.

  invokecc .LiteContinuation # or something ...

One more thing Leo (excuse my ignorance) why is there a stack calling 
convention in imcc? How does it relate to calling subs via the calling 
convention?

--
Jonathan Sillito



Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-11 Thread Luke Palmer
Jonathan Sillito writes:
 Here is another suggestion (I think I mentioned this in another email) we 
 could support a few different types of continuations. The simplest 
 continuation could be just a saved return address (i.e. an opcode_t*). 
 This would be roughly as lightweight as the current implementation, I 
 think. What do you think? I am thinking it would be easier to have one 
 calling convention then callees know what to expect.

   invokecc .LiteContinuation # or something ...

I like the idea.  One big thing that was discussed over on p6l is that
we want to make good coding style not incur a big performance
penalty, like may other languages do.  Considering the common
definition of good coding style, this means sub calls have to be as
cheap as possible.

One thing that worries me about the idea is whether it defeats the
benefits of a continuation passing style.  You can't bottle up a
LiteContinuation which only has the return address saved and store it
for later.  But then again, you can easily promote it if you need to,
by making a full-blown continuation that just returns to that spot.

I think with this style, though, that it's silly to use the register
stacks for sub calls... shouldn't those be stored in the continuation
instead?  I don't know how this would measure up performance-wise.
Anybody?


Luke


Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-10 Thread Jerome Vouillon
On Tue, Jun 10, 2003 at 06:07:31PM +, Jonathan Sillito wrote:
 I am not satisfied with the time taken to make a call. I did some rough
 benchmarking and the parrot implementation makes us slower than python
 2.2.1. The most expensive part of our call is the saveall/restoreall that
 wraps the invokecc. In some cases the caller can be more selective about
 what is saved, if no saveall/restoreall are used parrot calls are faster
 than python's. The PASM and python code I used to benchmark along with the
 times are below.
[...]

The python interpreter seems rather slow.  I get these numbers with the
Ocaml bytecode interpreter.

mistral-jerome:/tmp  time python test.py
python test.py  2,59s user 0,00s system 100% cpu 2,582 total
mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
./tst  0,14s user 0,00s system 106% cpu 0,131 total
mistral-jerome:/tmp  cat test.ml
let foo () = () in
for i = 1 to 100 do foo () done

-- Jerome


RE: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-10 Thread Jonathan Sillito
 -Original Message-
 From: Jerome Vouillon [mailto:[EMAIL PROTECTED]

 The python interpreter seems rather slow.  I get these numbers with the
 Ocaml bytecode interpreter.

 mistral-jerome:/tmp  time python test.py
 python test.py  2,59s user 0,00s system 100% cpu 2,582 total
 mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
 ./tst  0,14s user 0,00s system 106% cpu 0,131 total
 mistral-jerome:/tmp  cat test.ml
 let foo () = () in
 for i = 1 to 100 do foo () done

That is impressive. I don't know Ocaml but do you think there is an
optimization being done since foo takes no args, returns not values and has
an empty body?

Also I should have mentioned that python spends between one third and one
half of its time executing the loop instructions (test and increment).
Parrot is much faster at this of course.

Parrot sub and method calls can be made faster or slower depending on how
much of the context needs to be saved. I can imagine several types of
continuations that differ on how much context they save and restore:

 a. only an opcode ptr to jump to
 b. opcode and the stacks
 c. opcode, stacks and half of the registers
 d. opcode, stacks and all of the registers

The patch I sent supports two types: type b (in continuation.pmc) and type d
(in completecontext.pmc). Also in this patch is the option to not create a
new continuation --as in a tail call-- which of course makes it very fast.

--
Jonathan Sillito



Re: [perl #22633] [PATCH] convert parrot to continuation passing style

2003-06-10 Thread Robert Spier
  mistral-jerome:/tmp  time python test.py
  python test.py  2,59s user 0,00s system 100% cpu 2,582 total
  mistral-jerome:/tmp  ocamlc -o tst test.ml; time ./tst
  ./tst  0,14s user 0,00s system 106% cpu 0,131 total
  mistral-jerome:/tmp  cat test.ml
  let foo () = () in
  for i = 1 to 100 do foo () done
 
 That is impressive. I don't know Ocaml but do you think there is an
 optimization being done since foo takes no args, returns not values and has
 an empty body?

This also isn't a fair comparison.

python is compiling test.py to bytecode during the 'time' call.  

ocaml is explicitly compiling _to a raw executable_ (and optimizing at
three different levels) outside the call.  There's no startup overhead
for the binary.

Also, (in general) for this kind of test you really need to run each a
lot of times and average.  There's too many things going on on a
typical system that could tweak things.

-R