Here are the costs in seconds for running 100 million iterations of each
op. This only really makes sense on *my* machine, but it gives you an
idea of what sort of tradeoffs there are. Given that the difference between
most ops is negligible, I'd suggest that a lot of work is still happening
in the despatch.

The script which generated this is attached.

add_i                                   4.5
add_n                                   5
branch_ic                               2
dec_i                                   4.5
dec_i_ic                                4.5
dec_n                                   4.5
dec_n_nc                                6
div_i                                   10.5
div_n                                   24.5
eq_i_ic                                 4.5
eq_ic_ic                                4.5
eq_n_ic                                 5.5
eq_nc_ic                                6
ge_i_ic                                 5.5
ge_ic_ic                                5
ge_n_ic                                 6
ge_nc_ic                                6
gt_i_ic                                 5
gt_ic_ic                                5
gt_n_ic                                 5.5
gt_nc_ic                                6.5
if_i_ic                                 5
if_n_ic                                 6
inc_i                                   2
inc_i_ic                                4.5
inc_n                                   5
inc_n_nc                                5.5
iton_n_i                                6.5
le_i_ic                                 5
le_ic_ic                                5
le_n_ic                                 5.5
le_nc_ic                                5.5
length_i_s                              6
lt_i_ic                                 4.5
lt_ic_ic                                4.5
lt_n_ic                                 5
lt_nc_ic                                6
mod_i                                   11
mul_i                                   5.5
mul_n                                   6
ne_i_ic                                 4.5
ne_ic_ic                                4.5
ne_n_nc                                 5.5
ne_nc_ic                                5
noop                                    3.5
ntoi_i_n                                11.5
pushpop_i                               14
pushpop_n                               14
pushpop_p                               14
pushpop_s                               14
set_i                                   4.5
set_i_ic                                4.5
set_n_nc                                5
sub_i                                   5
sub_n                                   5
substr_s_s_i                            23.5
time_i                                  49.5
time_n                                  49.5

-- 
Simon:  `hello kitty' douche. If you are getting some and you know what
hello kitty is... Well, you're an exceptionally lucky man.
  -- Megahal, trained on IRC.
#!/usr/bin/perl -w
use strict;

$/="\n-----\n";

my $loops = 100_000_000;

print "Calibrating loop...\n";
my $cal = testit("","");
print "Empty loop took $cal seconds\n";

$| =1;
my %cost;
while (<DATA>) {
    chomp;
    my @lines = split /\n/,$_;
    my $name = shift @lines;
    print "Testing op $name...";
    my $setup ="";
    my $loop = "";
    
    if (($_ = shift @lines) eq "SETUP") { 
        $setup .= $_."\n" while $_ = shift @lines and $_ ne "LOOP" 
    } else {
        $loop = $_."\n";
    }
    $loop  .= join "\n", @lines;
    print $cost{$name} = testit($setup, $loop) - $cal;
    print "\n";
};

open COST, ">costmodel.tab" or die $!;
for (sort keys %cost) {
    print COST "$_", " " x (40-length($_)), $cost{$_},"\n";

}

sub testit {
    my ($setup, $loop) = @_;
    open PASM, ">cost.pasm" or die $!;
    unlink "cost.pbc";
    print PASM <<EOF;
        set_i_ic I33, $loops
        set_i_ic I32, 0
    set_i_ic I1, 0
    set_i_ic I2, 1
$setup
        time_i I31
REDO:   eq_i_ic I32, I33, DONE, NEXT
NEXT:   inc_i I32
# This is the main loop
$loop
# That was the main loop
        branch_ic REDO
DONE:   time_i I34
        sub_i  I34, I34, I31
        print_i I34
EOF
    system("perl assemble.pl cost.pasm > cost.pbc");
    die "Didn't assemble cleanly" unless -f "cost.pbc";
    # Average runs.
    my $a = `./test_prog cost.pbc`;
    my $b = `./test_prog cost.pbc`;
    return ($a+$b)/2;
}

__DATA__
add_i
    add_i I1, I2, I2
-----
sub_i
    sub_i I1, I2, I2
-----
mul_i
    mul_i I1, I2, I2
-----
div_i
    div_i I1, I2, I2
-----
mod_i
    mod_i I1, I2, I2
-----
set_i
    set_i I1, I2
-----
set_i_ic
    set_i_ic I1, 1
-----
eq_i_ic
    eq_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
eq_ic_ic
    eq_ic_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
ne_i_ic
    ne_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
ne_ic_ic
    ne_i_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
lt_i_ic
    lt_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
lt_ic_ic
    lt_ic_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
le_i_ic
    le_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
le_ic_ic
    le_i_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
gt_i_ic
    gt_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
gt_ic_ic
    gt_ic_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
ge_i_ic
    ge_i_ic I1, I2, MYNEXT, MYNEXT
    MYNEXT: 
-----
ge_ic_ic
    ge_i_ic I1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
if_i_ic
    if_i_ic I1, MYNEXT, MYNEXT
    MYNEXT: 
-----
time_i
    time_i I1
-----
branch_ic
    branch_ic MYNEXT
    MYNEXT:
-----
inc_i
    inc_i I1
-----
inc_i_ic
    inc_i_ic I1, 2
-----
dec_i
    dec_i I1
-----
dec_i_ic
    dec_i_ic I1, 2
-----
add_n
    add_n N1, N2, N2
-----
sub_n
    sub_n N1, N2, N2
-----
mul_n
    mul_n N1, N2, N2
-----
div_n
    div_n N1, N2, N2
-----
set_n_nc
    set_n_nc N1, 1
-----
eq_n_ic
    eq_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
eq_nc_ic
    eq_nc_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
ne_n_nc
    ne_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
ne_nc_ic 
    ne_n_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
lt_n_ic 
    lt_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
lt_nc_ic 
    lt_nc_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
le_n_ic 
    le_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
le_nc_ic 
    le_n_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
gt_n_ic 
    gt_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
gt_nc_ic 
    gt_nc_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
ge_n_ic 
    ge_n_ic N1, N2, MYNEXT, MYNEXT
    MYNEXT: 
-----
ge_nc_ic 
    ge_n_ic N1, 1, MYNEXT, MYNEXT
    MYNEXT: 
-----
if_n_ic 
    if_n_ic N1, MYNEXT, MYNEXT
    MYNEXT: 
-----
time_n
    time_n N1
-----
inc_n
    inc_n N1
-----
inc_n_nc 
    inc_n_nc N1, 2.0
-----
dec_n
    dec_n N1
-----
dec_n_nc 
    dec_n_nc N1, 2.0
-----
iton_n_i
    iton_n_i N1, I1
-----
ntoi_i_n
    ntoi_i_n I1, N1
-----
pushpop_i
    push_i
    pop_i
-----
pushpop_n
    push_n
    pop_n
-----
pushpop_s
    push_s
    pop_s
-----
pushpop_p
    push_p
    pop_p
-----
length_i_s
SETUP
    set_s_sc S1, "Hello world"
LOOP
    length_i_s I1, S1
-----
substr_s_s_i
SETUP
    set_s_sc S1, "Hello world"
    set_i_ic I1, 3
    set_i_ic I2, 4
# This saves a runtime allocation
    set_s_sc S2, ""
LOOP
    substr_s_s_i S2, S1, I1, I2
-----
noop
    noop

Reply via email to