I've implemented a (rather hackish and incomplete) new opcode called C<hyper>. Usage looks like:

    ar = new IntList
    ar = 1000000
    hyper
    ar = 10

or
    hyper
    ar += 10

The atached tests fill an integer array with one Meg int constants and then increment each value 5 times.

Here are the timing results (unoptimized parrot)
$ time  parrot -j  i.imc
6060

real 0m1.927s

$  time  parrot   ih.imc
6060

real 0m0.328s

Plain run core or JIT doesn't matter for the hyper version.

Only the set and add opcodes with constants are done. But it's not hard to extend the scheme and generalize it.

Comments welcome,
leo

$ cat ih.imc
.sub _main @MAIN
    loadlib P11, "myops_ops"
    .local pmc ar
    ar = new IntList
    ar = 1000000
    hyper
    ar = 10
    .local int j
    j = 0
lp1:
    hyper
    ar += 10
    inc j
    if j < 5 goto lp1
    set $I0, ar[0]
    print $I0
    set $I0, ar[999999]
    print $I0
    print "\n"
.end

$ cat i.imc
.sub _main @MAIN
    .local pmc ar
    ar = new IntList
    ar = 1000000
    .local int i
    i = 0
lp:
    ar[i] = 10
    inc i
    if i < 1000000 goto lp
    .local int j
    j = 0
lp1:
    i = 0
lp2:
    $I0 = ar[i]
    $I0 += 10
    ar[i] = $I0
    inc i
    if i < 1000000 goto lp2
    inc j
    if j < 5 goto lp1
    set $I0, ar[0]
    print $I0
    set $I0, ar[999999]
    print $I0
    print "\n"
.end

# from dynops/myops.ops
op hyper() {
    opcode_t *pc = expr NEXT();
    INTVAL i,l;
    UINTVAL c;
    op_info_t *opinfo = &interpreter->op_info_table[*pc];
    PMC *ar = REG_PMC(pc[1]);   /* TODO inspect opcode */
    List *list = PMC_data(ar);
    List_chunk *chunk;
    INTVAL v = pc[2], *p;
    int op = *pc;
    l = list_length(interpreter, list);
    i = 0;
    for (chunk = list->first; chunk; chunk = chunk->next) {
        if (chunk->flags & sparse)
            goto slow;
        p = PObj_bufstart(&chunk->data);
        for (c = 0; c < chunk->items; ++c, ++p) {
            switch (op) {
                case 906: /* set_p_ic */
                    *(INTVAL*) p = v;
                    break;
                case 460: /* add_p_ic */
                    *(INTVAL*) p += v;
                    break;
            }
        }
        i += c;
    }
    goto done;
slow:
    for (i; i < l; ++i)
        list_assign(interpreter, list, i, INTVAL2PTR(void*, v),
                enum_type_INTVAL);
done:
    pc += opinfo->arg_count;
    goto ADDRESS(pc);
}

PS needs latest CVS for a missing intlist vtable.



Reply via email to