Why doesn't JUMP_IF_FALSE do POP_TOP ?

Skip Montanaro skip at pobox.com
Mon Jan 13 12:44:49 EST 2003


>>>>> "Skip" == Skip Montanaro <skip at pobox.com> writes:

    Bengt> I.e., it should be simple to instrument ceval.c to extern link to
    Bengt> a temp module with an integer array indexed by byte code value to
    Bengt> increment for statistics.  

    Skip> You can already do this.  Simply define DYNAMIC_EXECUTION_PROFILES
    Skip> (and optionally DXPAIRS) when building Python.  

Perhaps I should also mention that I wrote an XML-RPC server awhile ago to
which people could submit instruction profiles as produced by the above
dynamic profiling macros.  I don't currently have it running, but if people
would like to start submitting profiles I'd be happy to start it up again.
Here's the output of the server's usage() method:

    The DXPServer allows people to store and retrieve dynamic
    instruction frequency information for Python programs.  It is
    hoped that by offering this service to the Python community a
    large database of instruction count frequencies can be accumulated
    for different versions of Python.

    The DXPserver currently implements just a few methods:

        add_dx_info(appname, email, pyversion, dxlist)
            Register the dynamic instruction frequencies for a single
            application run by a particular email address, using a
            particular version of Python.  There is no real useful
            return value unless an error is detected.

            appname: A non-empty string that identifies the
            application that generated this instruction profile.

            email: A valid email address (while this is logged, it
            will only be used to contact the owner of a misbehaving
            client).

            pyversion: A three-element tuple as returned by
            sys.version_info[:3].  People running pre-2.0 versions of
            Python will have to synthesize this from the first word of
            sys.version.  All three elements must be ints.

            dxlist: A run-length encoded version of the list returned
            by sys.getdxp().  You will only have this function
            available if you compiled your Python interpreter with the
            DYNAMIC_EXECUTION_PROFILE macro defined.  You can choose
            to define DXPAIRS as well or not.  This method accepts
            either type of getdxp() output.  The run-length encoding
            is described below.

        get_dx_info(pyversion)

            Return the instruction profiling information that has been
            accumulated for version pyversion.  The format for
            pyversion is the same as in add_dx_info.  The return value
            is a dictionary with two keys: 'counts' and 'pairs'.  The
            value associated with the 'counts' key is a run-length
            encoded list of opcode frequencies as would be returned by
            rle(sys.getdxp()) without DXPAIRS defined.  The value
            associated with the 'pairs' key is a list of opcode
            frequencies as would be returned by rle(sys.getdxp()) with
            DXPAIRS defined.  If there is no information recorded for
            one category or another appropriate zero-filled lists are
            returned.

        versions()
            Return the version numbers for which this server has some
            instruction counts.

        usage()
            Return detailed usage information.

        synopsis()
            Return brief usage information.

    The input dxlist and the output returned by get_dx_info must be
    run-length encoded.  The algorithm is straightforward:

        def rle(l):
            newl = []
            lastel = None
            count = 0
            for elt in l:
                if elt == lastel:
                    count = count + 1
                    continue
                elif lastel is not None:
                    if isinstance(lastel, types.ListType):
                        lastel = rle(lastel)
                    newl.append([lastel, count])
                lastel = elt
                count = 1
            if isinstance(lastel, types.ListType):
                lastel = rle(lastel)
            newl.append([lastel, count])
            return newl

    Use the following to run-length encode sys.getdxp() output:

        dxinfo = rle(sys.getdxp())

    Decoding is similar:

        def rld(l):
            newl = []
            for elt, count in l:
                if isinstance(elt, types.ListType):
                    elt = rld(elt)
                newl.extend([elt]*count)
            return newl

        dxinfo = rld(rpcserver.get_dx_info((1,5,2)))

    Both rle() and rld() are included in the dxpserver.py module/script
    available from <http://www.musi-cal.com/~skip/python/>.

    You can use the atexit module to automatically transmit instruction
    counts to the server at normal program termination:

        def send_instruction_counts(appname, email):
            if not hasattr(sys, 'getdxp'):
                return
            dxpserver = xmlrpclib.Server('http://manatee.mojam.com:7304')
            dxpserver.add_dx_info(appname, email, sys.version_info[:3],
                                  rle(sys.getdxp()))

        import atexit
        atexit.register(send_instruction_counts, 'myapp', 'me at some.where')

Skip





More information about the Python-list mailing list