interpreter vs. compiled

castironpi castironpi at gmail.com
Mon Jul 21 14:37:43 EDT 2008


On Jul 18, 2:13 pm, Dan <thermos... at gmail.com> wrote:
> On Jul 18, 2:17 pm, castironpi <castiro... at gmail.com> wrote:
>
>
>
> > On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu... at gmx.net> wrote:
>
> > > On 18 Jul., 01:15, castironpi <castiro... at gmail.com> wrote:
>
> > > > On Jul 17, 5:37 pm, I V <ivle... at gmail.com> wrote:
>
> > > > > On Thu, 17 Jul 2008 15:08:17 -0700, castironpi wrote:
> > > > > > The Python disassembly is baffling though.
>
> > > > > >>>> y= 3
> > > > > >>>> dis.dis('x=y+1')
>
> > > > > You can't disassemble strings of python source (well, you can, but, as
> > > > > you've seen, the results are not meaningful). You need to compile the
> > > > > source first:
>
> > > > > >>> code = compile('y=x+1','-', 'single')
> > > > > >>> dis.dis(code)
>
> > > > >   1           0 LOAD_NAME                0 (x)
> > > > >               3 LOAD_CONST               0 (1)
> > > > >               6 BINARY_ADD
> > > > >               7 STORE_NAME               1 (y)
> > > > >              10 LOAD_CONST               1 (None)
> > > > >              13 RETURN_VALUE
>
> > > > > You may well find these byte codes more meaningful. Note that there is a
> > > > > list of opcodes athttp://docs.python.org/lib/bytecodes.html
>
> > > > Oh.  How is the stack represented?
>
> > > As a pointer to a pointer of PyObject structs.
>
> > > > Does it keep track of which stack
> > > > positions (TOS, TOS1, etc.) are in what registers?  Does stack
> > > > manipulation consume processor cycles?
>
> > > Python does not store values in registers. It stores locals in arrays
> > > and accesses them by position ( you can see the positional index in
> > > the disassembly right after the opcode name ) and globals / object
> > > attributes in dicts.
>
> > > For more information you might just download the source distribution
> > > and look for src/Python/ceval.c. This file contains the main
> > > interpreter loop.
>
> > Ah, found it.  The parts that are making sense are:
>
> > register PyObject **stack_pointer;
> > #define TOP()           (stack_pointer[-1])
> > #define BASIC_POP()     (*--stack_pointer)
>
> > ...(line 1159)...
> > w = POP();
> > v = TOP();
> > if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
> >         /* INLINE: int + int */
> >         register long a, b, i;
> >         a = PyInt_AS_LONG(v);
> >         b = PyInt_AS_LONG(w);
> >         i = a + b;
> >         if ((i^a) < 0 && (i^b) < 0)
> >                 goto slow_add;
> >         x = PyInt_FromLong(i);
>
> > ... Which is more than I was picturing was involved.  I understand it
> > is also specific to CPython.  Thanks for the pointer to the code.
>
> > My basic question was, what is the difference between compilers and
> > interpreters, and why are interpreters slow?  I'm looking at some of
> > the answer right now in "case BINARY_ADD:".
>
> The basic difference between a (traditional) compiler and an
> interpreter is that a compiler emits (assembly) code for a specific
> machine. Therefore it must know the specifics of the machine (how many
> registers, memory addressing modes, etc), whereas interpreters
> normally define themselves by their conceptual state, that is, a
> virtual machine. The instructions (bytecode) of the virtual machine
> are generally more high-level than real machine instructions, and the
> semantics of the bytecode are implemented by the interpreter, usually
> in a sort-of high level language like C. This means the interpreter
> can run without detailed knowledge of the machine as long as a C
> compiler exists. However, the trade off is that the interpreter
> semantics are not optimized for that machine.
>
> This all gets a little more hairy when you start talking about JITs,
> runtime optimizations, and the like. For a real in-depth look at the
> general topic of interpretation and virtual machines, I'd recommend
> Virtual Machines by Smith and Nair (ISBN:1-55860910-5).
>
> -Dan

You're saying the VM can't compile code.  That makes sense, it's not a
compiler.  Do I understand correctly that JIT does compile to native
code in some cases?

Python: x= y+ 1
Python VM: push, push, add, store
Assembly: load, load, add, store

Except, the assembly doesn't contain the type-checking that
PyInt_AS_LONG does.  But that's not the only thing that stops python
from precompiling to assembly directly.  GNU doesn't come with
Python.  What sorts of minimal information would be necessary to take
from the GNU libs for the user's specific processor, (the one they're
downloading their version of Python for), to move Python to the
further step of outputting the machine code?



More information about the Python-list mailing list