Sam Ruby <[EMAIL PROTECTED]> wrote:
> Leopold Toetsch wrote:

>> Well, and that's not true. I've already shown the opposite:
>> Here are agains these numbers (-O3 build, AMD 800, 5 Meg operations):
>>
>> MMD add PerlInt PerlInt 0.693220
>> MMD add PerlInt INTVAL  0.609069
>> MMD sub PerlInt PerlInt 0.475912
>> MMD sub PerlInt INTVAL  0.490149
>> PIR add PerlInt PerlInt 8.312403
>> PIR sub PerlInt PerlInt 4.562026
>>
>> Please note the big speedup in the overloaded sub method.

> In this table, are bigger numbers good or bad?  Which of MMD or PIR
> corresponds to callmethod?

Sorry, forgot to mention - execution time in seconds.

> I would have assumed that sub mapped to MMD, and small (i.e., good)
> numbers, and that callmethod mapped to PIR and big (i.e., bad) numbers.

The "add" are current opcodes/functionality - either the plain MMD add
opcode or an overloaded function implemented in PIR.

The "sub" is the scheme with the PIC locally running here. The MMD "sub"
is not a full method call as it takes arguments. It's like

  call_mmd "sub", P0, P1, P2

This does once a method lookup - it consults the MMD_table for the left
and right types and caches the function pointer / type pair.
If the return method PMC is a Sub the bytecode is rewritten to an opcode
that runs the PIR "sub" function.

Summary: the method call scheme with PIC is faster for MMD operations,
slightly slower for vtable functions and almost double speed for
overloaded method functions.

Below is the full code of the benchmark.

> Am I reading this wrong?

Partly, yes.

> I don't see a Python compiler ever emitting a "sin" opcode.

Yes that what I'm talking about. We need methods.

> The code for pie-thon was based on the incorrect assumption that
> builtins are both global and reserved.

Yep, that was broken. I knew it ;)

> ... The truth is that all such
> symbols are lexically scoped in Python.

Where AFAIK the topmost lexical pad corresponds to Python's "global".

> Pirate currently emits the following code for "print sin(1+2j)":

> .sub __main__ @MAIN

>      find_lex $P4, 'sin'           # (lookupName:142)
>      $P3=$P4($P0)                  # (callingExpression:567)

Cool. But to make that work you need somewhere a "sin" method in a
namespace, i.e.

  METHOD PMC* sin(PMC *num) {}

in Complex.pmc. And there is another "sin" method in another namespace
doing a sinus for FLOATVALS. During __load__ you are aliasing the "sin"
method as a lexical. This step is corresponding to the "import"
statement.

OTOH when you have

  math.sin(2)

Python emits:

  6          44 LOAD_NAME                0 (math)
             47 LOAD_ATTR                1 (sin)
             50 LOAD_CONST               1 (2)
             53 CALL_FUNCTION            1

which actually is a method call on the "math" object. And the math
object is a namespace alias of e.g. the Float PMC.

Given that Python and Perl and other languages will just use this
method, it should be implemented in core PMCs (Complex, Float).

The same is true for all other stuff that is currently a vtable only
like "__getitem__" or just unimplemented, like all the trig functions
for PMCs.

leo

$ cat mmd-bench.imc

.sub _main prototyped
    .const int max = 5000000
    .const int val = 3
    $P0 = new PerlInt
    $P1 = new PerlInt
    $P2 = new PerlInt
    $P1 = 10
    $P2 = val
    .local float start
    start = time
    .local int i
    i = 0
lp1:
    $P0 = $P1 + $P2
    inc i
    if i < max goto lp1
    $N0 = time
    $N0 -= start
    print "MMD add PerlInt PerlInt "
    print $N0
    print "\n"

    $P0 = new PerlInt
    $P1 = new PerlInt
    $P1 = 10
    $I2 = val
    .local float start
    start = time
    .local int i
    i = 0
lp2:
    $P0 = $P1 + $I2
    inc i
    if i < max goto lp2
    $N0 = time
    $N0 -= start
    print "MMD add PerlInt INTVAL  "
    print $N0
    print "\n"


    $P0 = new PerlInt
    $P1 = new PerlInt
    $P2 = new PerlInt
    $P1 = 10
    $P2 = val
    .local float start
    start = time
    .local int i
    i = 0
lp3:
    $P0 = $P1 - $P2
    inc i
    if i < max goto lp3
    $N0 = time
    $N0 -= start
    print "MMD sub PerlInt PerlInt "
    print $N0
    print "\n"

    $P0 = new PerlInt
    $P1 = new PerlInt
    $P1 = 10
    $I2 = val
    .local float start
    start = time
    .local int i
    i = 0
lp4:
    $P0 = $P1 - $I2
    inc i
    if i < max goto lp4
    $N0 = time
    $N0 -= start
    print "MMD sub PerlInt INTVAL  "
    print $N0
    print "\n"

.include "mmd.pasm"
    $P0 = new PerlInt
    $P1 = new PerlInt
    $P2 = new PerlInt
    $P1 = 10
    $P2 = val
    find_global $P19, "PerlInt_add_pp"
    mmdvtregister .MMD_ADD, .PerlInt, .PerlInt, $P19
    .local float start
    start = time
    .local int i
    i = 0
lp5:
    $P0 = $P1 + $P2
    inc i
    if i < max goto lp5
    $N0 = time
    $N0 -= start
    print "PIR add PerlInt PerlInt "
    print $N0
    print "\n"

    $P0 = new PerlInt
    $P1 = new PerlInt
    $P2 = new PerlInt
    $P1 = 10
    $P2 = val
    find_global $P19, "PerlInt_sub_pp"
    mmdvtregister .MMD_SUBTRACT, .PerlInt, .PerlInt, $P19
    .local float start
    start = time
    .local int i
    i = 0
lp6:
    $P0 = $P1 - $P2
    inc i
    if i < max goto lp6
    $N0 = time
    $N0 -= start
    print "PIR sub PerlInt PerlInt "
    print $N0
    print "\n"
    end
.end

.sub PerlInt_add_pp prototyped
    .param pmc left
    .param pmc right
    .param pmc dest
    $I16 = left
    $I17 = right
    $I18 = $I16 + $I17
    dest = $I18
.end
.sub PerlInt_sub_pp prototyped
    .param pmc left
    .param pmc right
    .param pmc dest
    $I16 = left
    $I17 = right
    $I18 = $I16 - $I17
    dest = $I18
.end

Reply via email to