Ken Fox ("perl6 Kakapo") has mailed me a link [1] and some hints about PIC - Polymorphic Inline Cache.

This is quite an interesting idea about dynamic recompiling and caching of method lookups. And it smells like more MOPS and generally just a faster Parrot VM. So I've hacked together an initial version for testing, only MMD lookups currently.

PMC MOPS (examples/benchmarks/mops.pasm)

parrot -C CVS    13.6
parrot -j        13.4
parrot -C PIC    16.7

This is a 22% speedup for MOPS and very likely more for method lookups.
With JIT_CGP the JIT core could also use this optimization.
(Numbers with -O3 build, AMD 800)

Below is a (very) preliminary pod generated from src/pic.c.

Before spending more time on that, I'd like to hear some comments about possible hidden drawbacks or whatever. I can provide a patch too.

Thanks,
leo

[1] http://citeseer.ist.psu.edu/hlzle91optimizing.html


PIC.C(1)       User Contributed Perl Documentation       PIC.C(1)


NNNNAAAAMMMMEEEE
       src/pic.c - Polymorphic Inline Cache

DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
       The PIC supports inline caching for MMD and object method
       lookups in the CGP (direct threaded run core).

       ·   During predereferencing the bytecode,
           Parrot_PIC_prederef() is called. If it's a MMD
           function, the prederefed code pointer is replaced with
           a stub that caches MMD lookups. For callmethod opcodes
           another stub is created that caches classes or does a
           method lookup.

       ·   This stub inside pic_cgp_core checks the PMC types. If
           a match with the cache is found the MMD function is
           called directly.  If no match is found the MMD
           function is looked up, and function pointer and types
           are stored in the cache.

       ·   For objects, the cache holds entries per
           class/method_name.

       TODO

         - create a circular LRU buffer for a few types.
         - cache all MMD functions
         - cache method lookups
         - provide an API to invalidate the cache per class or all.


       FFFFuuuunnnnccccttttiiiioooonnnnssss


       static opcode_t *pic_cgp_core(opcode_t *cur_op, Interp*)
           This has the same signature and usage as the cgp_core.
           Actually this function is just used to return the
           address of the CGoto jump table. The code is executed
           by just jumping inside the labels (from and to the CGP
           core).

       static void pic_create_mmd(Interp *, opcode_t *pc, void
       **pc_pred, INTVAL func_nr)
           Create a PIC structure for the given MMD func_nr. The
           *pc is the plain bytecode pointer, pc_pred points into
           the prederefed code.

           The first argument of the opcode gets the pic
           structure, which has as slot first_arg, where this
           argument is preserved. A typical opcode with a PIC
           looks like:

             [opcode] [pic] [left] [right]




20/Nov/2004                 perl 5.008                          1





PIC.C(1)       User Contributed Perl Documentation       PIC.C(1)


           The [dest] argument is in the PIC struture.

       void Parrot_PIC_prederef(Interp *, opcode_t *pc, void
       **pc_pred)
           Define either the normal prederef function or the PIC
           stub, if PIC for this opcode function is available.
           Called from do_prederef.

AAAAUUUUTTTTHHHHOOOORRRR
       Leopold Toetsch with many hints from Ken Fox.

SSSSEEEEEEEE AAAALLLLSSSSOOOO
       _s_r_c_/_m_m_d_._c, _s_r_c_/_o_b_j_e_c_t_._c, 
_s_r_c_/_i_n_t_e_r_p_r_e_t_e_r_._c,
       _o_p_s_/_c_o_r_e___o_p_s___c_g_p_._c











































20/Nov/2004                 perl 5.008                          2


Reply via email to