Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

interpreter vs. compiled

 

 

First page Previous page 1 2 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded


castironpi at gmail

Jul 17, 2008, 3:08 PM

Post #1 of 48 (727 views)
Permalink
interpreter vs. compiled

I'm curious about some of the details of the internals of the Python
interpreter:

I understand C from a hardware perspective.

x= y+ 1;

Move value from place y into a register
Add 1 to the value in the register
Move the addition's result to place x

The Python disassembly is baffling though.

>>> y= 3
>>> dis.dis('x=y+1')
0 SETUP_LOOP 31037 (to 31040)
3 STORE_SLICE+3
4 <49>

What are SETUP_LOOP and STORE_SLICE? What are these instructions?
--
http://mail.python.org/mailman/listinfo/python-list


ivlenin at gmail

Jul 17, 2008, 3:37 PM

Post #2 of 48 (709 views)
Permalink
Re: interpreter vs. compiled [In reply to]

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 at http://docs.python.org/lib/bytecodes.html
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 17, 2008, 4:15 PM

Post #3 of 48 (699 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 17, 5:37 pm, I V <ivle...@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? Does it keep track of which stack
positions (TOS, TOS1, etc.) are in what registers? Does stack
manipulation consume processor cycles? Here is what I'm thinking:

LOAD_NAME: stack= [ x ]
reg0: x
tos: reg0
LOAD_CONST: stack= [ 1, x ]
reg0: x
reg1: 1
tos: reg1
BINARY_ADD: stack= [ x+ 1, x ]
reg0: x
reg1: x+ 1
tos: reg1
STORE_NAME: y= [ x+ 1], stack= same
reg0: x
reg1: x+ 1
tos: reg1

I may be totally off.
--
http://mail.python.org/mailman/listinfo/python-list


tjreedy at udel

Jul 17, 2008, 6:47 PM

Post #4 of 48 (699 views)
Permalink
Re: interpreter vs. compiled [In reply to]

castironpi wrote:
> On Jul 17, 5:37 pm, I V <ivle...@gmail.com> wrote:
>
>
> Oh. How is the stack represented?

As usual, as successive locations in memory.
I have the impression that CPython uses the same stack C does.
While conceptually, CPython may put objects on the stack, I am pretty
sure it actually stacks references (C pointers) to objects in heap memory.

> Does it keep track of which stack
> positions (TOS, TOS1, etc.) are in what registers?

I am sure they are not in registers, just normal memory.
The C code that implements bytecodes to act on stack values will use
registers just like any other C code. So using registers for the stack
would get in the way. Of course, the C code might load pointers on the
stack into address registers when actually needed. But this depends on
the address scheme of a particular processor and how the C code is
compiled to its object code.

> Does stack manipulation consume processor cycles?

Of course. For much more, you should peruse the CPython source.

--
http://mail.python.org/mailman/listinfo/python-list


kay.schluehr at gmx

Jul 17, 2008, 9:39 PM

Post #5 of 48 (700 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On 18 Jul., 01:15, castironpi <castiro...@gmail.com> wrote:
> On Jul 17, 5:37 pm, I V <ivle...@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.

--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 17, 2008, 11:31 PM

Post #6 of 48 (689 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu...@gmx.net> wrote:
> On 18 Jul., 01:15, castironpi <castiro...@gmail.com> wrote:
>
>
>
> > On Jul 17, 5:37 pm, I V <ivle...@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.

Oh. I was interpreting, no pun, that the column of numbers to the
left indicated how many processor cycles were consumed in each
operation. It doesn't quite make sense, unless BINARY_ADD can refer
to memory outside of the registers, which I doubt on the basis that
two addresses would have to fit into a single operation, plus the
architecture opcode. Given that, what does that column indicate?

I'm intimidated by the source but I may look.
--
http://mail.python.org/mailman/listinfo/python-list


m.liu.jin at gmail

Jul 17, 2008, 11:58 PM

Post #7 of 48 (690 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 18, 2:31 pm, castironpi <castiro...@gmail.com> wrote:
> Given that, what does that column indicate?

Offset.
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 18, 2008, 11:17 AM

Post #8 of 48 (681 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu...@gmx.net> wrote:
> On 18 Jul., 01:15, castironpi <castiro...@gmail.com> wrote:
>
>
>
> > On Jul 17, 5:37 pm, I V <ivle...@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:".
--
http://mail.python.org/mailman/listinfo/python-list


thermostat at gmail

Jul 18, 2008, 12:13 PM

Post #9 of 48 (685 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 18, 2:17 pm, castironpi <castiro...@gmail.com> wrote:
> On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu...@gmx.net> wrote:
>
>
>
> > On 18 Jul., 01:15, castironpi <castiro...@gmail.com> wrote:
>
> > > On Jul 17, 5:37 pm, I V <ivle...@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
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 21, 2008, 11:37 AM

Post #10 of 48 (658 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 18, 2:13 pm, Dan <thermos...@gmail.com> wrote:
> On Jul 18, 2:17 pm, castironpi <castiro...@gmail.com> wrote:
>
>
>
> > On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu...@gmx.net> wrote:
>
> > > On 18 Jul., 01:15, castironpi <castiro...@gmail.com> wrote:
>
> > > > On Jul 17, 5:37 pm, I V <ivle...@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?
--
http://mail.python.org/mailman/listinfo/python-list


timr at probo

Jul 22, 2008, 9:38 PM

Post #11 of 48 (660 views)
Permalink
Re: interpreter vs. compiled [In reply to]

castironpi <castironpi[at]gmail.com> wrote:
>
>You're saying the VM can't compile code. That makes sense, it's not a
>compiler.

I wouldn't say "can't". The current CPython VM does not compile code. It
COULD. The C#/.NET VM does. IronPython, for example, is an implementation
of Python that uses .NET. In that case, the code *IS* JIT compiled to
assembly when the program starts.

>Do I understand correctly that JIT does compile to native
>code in some cases?

VMs that use JIT do, yes.

>But that's not the only thing that stops python
>from precompiling to assembly directly. GNU doesn't come with
>Python.

Do you mean Linux?

>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?

I don't know why you think GNU has anything to do with this. There's
nothing that prevents the Python run-time from JIT compiling the code.
IronPython does this. CPython does not. It's an implementation decision.
--
Tim Roberts, timr[at]probo.com
Providenza & Boekelheide, Inc.
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 23, 2008, 9:38 AM

Post #12 of 48 (645 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 22, 11:38 pm, Tim Roberts <t...@probo.com> wrote:
> castironpi <castiro...@gmail.com> wrote:
>
> >You're saying the VM can't compile code.  That makes sense, it's not a
> >compiler.
>
> I wouldn't say "can't".  The current CPython VM does not compile code.  It
> COULD.  The C#/.NET VM does.  IronPython, for example, is an implementation
> of Python that uses .NET.  In that case, the code *IS* JIT compiled to
> assembly when the program starts.
>
> >Do I understand correctly that JIT does compile to native
> >code in some cases?
>
> VMs that use JIT do, yes.
>
> >But that's not the only thing that stops python
> >from precompiling to assembly directly.  GNU doesn't come with
> >Python.
>
> Do you mean Linux?
>
> >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?
>
> I don't know why you think GNU has anything to do with this.  There's
> nothing that prevents the Python run-time from JIT compiling the code.
> IronPython does this.  CPython does not.  It's an implementation decision.
> --
> Tim Roberts, t...@probo.com
> Providenza & Boekelheide, Inc.

Compiling a program is different than running it. A JIT compiler is a
kind of compiler and it makes a compilation step. I am saying that
Python is not a compiler and in order to implement JIT, it would have
to change that fact.

> of Python that uses .NET. In that case, the code *IS* JIT compiled to
> assembly when the program starts.

But still not the user's code, only the interpreter, which is running
in assembly already anyway in CPython.
--
http://mail.python.org/mailman/listinfo/python-list


martin at v

Jul 23, 2008, 10:08 AM

Post #13 of 48 (648 views)
Permalink
Re: interpreter vs. compiled [In reply to]

>> Oh. How is the stack represented?
>
> As usual, as successive locations in memory.
> I have the impression that CPython uses the same stack C does.

Actually, it doesn't (at least not for the evaluation stack).

In CPython, when a Python function starts, the maximum depth of the
evaluation stack is known, but it depends on the specific function
(of course). So Python needs to allocate an array for the evaluation
stack with known size, but can't do so on the C stack (at least not
portably), since you can't allocate dynamically-sized array as
a local variable in C.

So instead, pymalloc is used to allocate the evaluation stack, and
it is part of the frame object (so the entire frame object is allocated
in one chunk, and then split up into local variables and evaluation
stack.

> While conceptually, CPython may put objects on the stack, I am pretty
> sure it actually stacks references (C pointers) to objects in heap memory.

Correct.

>> Does it keep track of which stack
>> positions (TOS, TOS1, etc.) are in what registers?
>
> I am sure they are not in registers, just normal memory.

Correct. As discussed above, they are located on the heap (making
Python's frame stack a spaghetti stack).

Regards,
Martin
--
http://mail.python.org/mailman/listinfo/python-list


fredrik at pythonware

Jul 23, 2008, 1:18 PM

Post #14 of 48 (648 views)
Permalink
Re: interpreter vs. compiled [In reply to]

castironpi wrote:

> Compiling a program is different than running it. A JIT compiler is a
> kind of compiler and it makes a compilation step. I am saying that
> Python is not a compiler and in order to implement JIT, it would have
> to change that fact.

good thing Python don't have to listen to you, then, so it can keep
using its built-in compiler to produce programs for its built-in VM.

> But still not the user's code, only the interpreter, which is running
> in assembly already anyway in CPython.

good luck with your future career in computing!

</F>

--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 23, 2008, 9:35 PM

Post #15 of 48 (641 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 23, 12:08 pm, "Martin v. Löwis" <mar...@v.loewis.de> wrote:
> >> Oh.  How is the stack represented?
>
> > As usual, as successive locations in memory.
> > I have the impression that CPython uses the same stack C does.
>
> Actually, it doesn't (at least not for the evaluation stack).
>
> In CPython, when a Python function starts, the maximum depth of the
> evaluation stack is known, but it depends on the specific function
> (of course). So Python needs to allocate an array for the evaluation
> stack with known size, but can't do so on the C stack (at least not
> portably), since you can't allocate dynamically-sized array as
> a local variable in C.
>
> So instead, pymalloc is used to allocate the evaluation stack, and
> it is part of the frame object (so the entire frame object is allocated
> in one chunk, and then split up into local variables and evaluation
> stack.
>
> > While conceptually, CPython may put objects on the stack, I am pretty
> > sure it actually stacks references (C pointers) to objects in heap memory.
>
> Correct.
>
> >> Does it keep track of which stack
> >> positions (TOS, TOS1, etc.) are in what registers?
>
> > I am sure they are not in registers, just normal memory.
>
> Correct. As discussed above, they are located on the heap (making
> Python's frame stack a spaghetti stack).
>
> Regards,
> Martin

Martin,

I am curious and pursuing it as an independent project. I'd like to
write a specialized function to allocate memory from an memory-mapped
file instead of the heap. On Windows, to use CreateFileMapping and
MapViewOfFile. The companion function, premalloc, would re-open an
existing Python object from a handle. (It would need a name or index -
> offset look-up.)

svn.python.org is down, so I can't tell if Python already implements
its own memory management, and if so how that would extrapolate to a
byte-array allocated specifically.
--
http://mail.python.org/mailman/listinfo/python-list


timr at probo

Jul 24, 2008, 9:04 PM

Post #16 of 48 (629 views)
Permalink
Re: interpreter vs. compiled [In reply to]

castironpi <castironpi[at]gmail.com> wrote:
>
>Compiling a program is different than running it. A JIT compiler is a
>kind of compiler and it makes a compilation step. I am saying that
>Python is not a compiler and in order to implement JIT, it would have
>to change that fact.

And I'm saying you are wrong. There is NOTHING inherent in Python that
dictates that it be either compiled or interpreted. That is simply an
implementation decision. The CPython implementation happens to interpret.
The IronPython implementation compiles the intermediate language to native
machine language.

>> of Python that uses .NET. In that case, the code *IS* JIT compiled to
>> assembly when the program starts.
>
>But still not the user's code, only the interpreter, which is running
>in assembly already anyway in CPython.

In CPython, yes. In IronPython, no; the user's code is compiled into
machine language. Both of them are "Python".
--
Tim Roberts, timr[at]probo.com
Providenza & Boekelheide, Inc.
--
http://mail.python.org/mailman/listinfo/python-list


bob.martin at excite

Jul 25, 2008, 2:56 AM

Post #17 of 48 (626 views)
Permalink
Re: interpreter vs. compiled [In reply to]

in 75186 20080725 050433 Tim Roberts <timr[at]probo.com> wrote:
>castironpi <castironpi[at]gmail.com> wrote:
>>
>>Compiling a program is different than running it. A JIT compiler is a
>>kind of compiler and it makes a compilation step. I am saying that
>>Python is not a compiler and in order to implement JIT, it would have
>>to change that fact.
>
>And I'm saying you are wrong. There is NOTHING inherent in Python that
>dictates that it be either compiled or interpreted. That is simply an
>implementation decision. The CPython implementation happens to interpret.
>The IronPython implementation compiles the intermediate language to native
>machine language.
>
>>> of Python that uses .NET. In that case, the code *IS* JIT compiled to
>>> assembly when the program starts.
>>
>>But still not the user's code, only the interpreter, which is running
>>in assembly already anyway in CPython.
>
>In CPython, yes. In IronPython, no; the user's code is compiled into
>machine language. Both of them are "Python".
>--
>Tim Roberts, timr[at]probo.com
>Providenza & Boekelheide, Inc.

It's amazing how many people cannot differentiate between language and implementation.
How many times have I read "x is an interpreted language"?
I know many languages are designed for either compilation or interpretation, but I have
used C and Pascal interpreters as well as Java and Rexx compilers.
--
http://mail.python.org/mailman/listinfo/python-list


nagle at animats

Jul 25, 2008, 11:24 AM

Post #18 of 48 (618 views)
Permalink
Re: interpreter vs. compiled [In reply to]

Tim Roberts wrote:
> And I'm saying you are wrong. There is NOTHING inherent in Python that
> dictates that it be either compiled or interpreted. That is simply an
> implementation decision. The CPython implementation happens to interpret.
> The IronPython implementation compiles the intermediate language to native
> machine language.

Well, actually there are some Python language features which make
static compilation to machine code difficult. PyPy and Shed Skin
have to impose some restrictions on dynamism to make efficient
compilation feasible. The big problem is "hidden dynamism", where the code
looks static, but at run time, some external piece of code replaces a
function or adds an unexpected attribute to what looked like a simple object
or function in the defining module.

In CPython, everything is a general object internally, and all the
names are resolved over and over again at run time by dictionary lookup.
This is simple, but there's a sizable speed penalty.

John Nagle
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 26, 2008, 10:02 PM

Post #19 of 48 (593 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 24, 11:04 pm, Tim Roberts <t...@probo.com> wrote:
> castironpi <castiro...@gmail.com> wrote:
>
> >Compiling a program is different than running it.  A JIT compiler is a
> >kind of compiler and it makes a compilation step.  I am saying that
> >Python is not a compiler and in order to implement JIT, it would have
> >to change that fact.
>
> And I'm saying you are wrong.  There is NOTHING inherent in Python that
> dictates that it be either compiled or interpreted.  That is simply an
> implementation decision.  The CPython implementation happens to interpret.
> The IronPython implementation compiles the intermediate language to native
> machine language.
>
> >> of Python that uses .NET.  In that case, the code *IS* JIT compiled to
> >> assembly when the program starts.
>
> >But still not the user's code, only the interpreter, which is running
> >in assembly already anyway in CPython.
>
> In CPython, yes.  In IronPython, no; the user's code is compiled into
> machine language.  Both of them are "Python".
> --
> Tim Roberts, t...@probo.com
> Providenza & Boekelheide, Inc.

In CPython yes. In IronPython yes: the parts that are compiled into
machine code are the interpreter, *not user's code*. Without that
step, the interpreter would be running on an interpreter, but that
doesn't get the user's statement 'a= b+ 1' into registers-- it gets
'push, push, add, pop' into registers.

--
http://mail.python.org/mailman/listinfo/python-list


fuzzyman at gmail

Jul 28, 2008, 3:58 PM

Post #20 of 48 (569 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 27, 6:02 am, castironpi <castiro...@gmail.com> wrote:
> On Jul 24, 11:04 pm, Tim Roberts <t...@probo.com> wrote:
>
>
>
> > castironpi <castiro...@gmail.com> wrote:
>
> > >Compiling a program is different than running it.  A JIT compiler is a
> > >kind of compiler and it makes a compilation step.  I am saying that
> > >Python is not a compiler and in order to implement JIT, it would have
> > >to change that fact.
>
> > And I'm saying you are wrong.  There is NOTHING inherent in Python that
> > dictates that it be either compiled or interpreted.  That is simply an
> > implementation decision.  The CPython implementation happens to interpret.
> > The IronPython implementation compiles the intermediate language to native
> > machine language.
>
> > >> of Python that uses .NET.  In that case, the code *IS* JIT compiled to
> > >> assembly when the program starts.
>
> > >But still not the user's code, only the interpreter, which is running
> > >in assembly already anyway in CPython.
>
> > In CPython, yes.  In IronPython, no; the user's code is compiled into
> > machine language.  Both of them are "Python".
> > --
> > Tim Roberts, t...@probo.com
> > Providenza & Boekelheide, Inc.
>
> In CPython yes.  In IronPython yes:  the parts that are compiled into
> machine code are the interpreter, *not user's code*.  Without that
> step, the interpreter would be running on an interpreter, but that
> doesn't get the user's statement 'a= b+ 1' into registers-- it gets
> 'push, push, add, pop' into registers.

Well - in IronPython user code gets compiled to in memory assemblies
which can be JIT'ed.

Michael Foord
--
http://www.ironpythoninaction.com/
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 28, 2008, 9:21 PM

Post #21 of 48 (568 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 28, 5:58 pm, Fuzzyman <fuzzy...@gmail.com> wrote:
> On Jul 27, 6:02 am, castironpi <castiro...@gmail.com> wrote:
>
>
>
> > On Jul 24, 11:04 pm, Tim Roberts <t...@probo.com> wrote:
>
> > > castironpi <castiro...@gmail.com> wrote:
>
> > > >Compiling a program is different than running it.  A JIT compiler is a
> > > >kind of compiler and it makes a compilation step.  I am saying that
> > > >Python is not a compiler and in order to implement JIT, it would have
> > > >to change that fact.
>
> > > And I'm saying you are wrong.  There is NOTHING inherent in Python that
> > > dictates that it be either compiled or interpreted.  That is simply an
> > > implementation decision.  The CPython implementation happens to interpret.
> > > The IronPython implementation compiles the intermediate language to native
> > > machine language.
>
> > > >> of Python that uses .NET.  In that case, the code *IS* JIT compiled to
> > > >> assembly when the program starts.
>
> > > >But still not the user's code, only the interpreter, which is running
> > > >in assembly already anyway in CPython.
>
> > > In CPython, yes.  In IronPython, no; the user's code is compiled into
> > > machine language.  Both of them are "Python".
> > > --
> > > Tim Roberts, t...@probo.com
> > > Providenza & Boekelheide, Inc.
>
> > In CPython yes.  In IronPython yes:  the parts that are compiled into
> > machine code are the interpreter, *not user's code*.  Without that
> > step, the interpreter would be running on an interpreter, but that
> > doesn't get the user's statement 'a= b+ 1' into registers-- it gets
> > 'push, push, add, pop' into registers.
>
> Well - in IronPython user code gets compiled to in memory assemblies
> which can be JIT'ed.
>
> Michael Foord
> --http://www.ironpythoninaction.com/

I don't believe so.

Take a sample interpreted language, to be compiled by a sample JIT.

a= stack( )
a.push( 0 )
a.push( 2 )
a.push( 4 )

Bytecode output is:

allocate var0
call STACK_CONSTRUCTOR
initialize var0 return
call METH0 var0 const 0
call METH0 var0 const 2
call METH0 var0 const 4

JIT output is assembly:

reg0 malloc 4
setjmp
jmp STACK_CONSTRUCTOR
popjmpv reg1
setjmp
reg1 0
jmp METH0
reg1 2
jmp METH0
reg1 4
jmp METH0

But when you compare the C code for 'x= y+ 1' to Python JIT code for
'x= y+ 1', there is no stack and no error checking. They're quite
different. In a JIT language, Python runs in native assembly, output
similar to CPython, theoretically. User's code -does- -not- -run-.
It is moved in to and out of a stack by a program that is running,
namely the interpreter, whether it came from C and a compiler,
or .NEt, bytecode, and a JIT.
--
http://mail.python.org/mailman/listinfo/python-list


timr at probo

Jul 28, 2008, 11:46 PM

Post #22 of 48 (569 views)
Permalink
Re: interpreter vs. compiled [In reply to]

castironpi <castironpi[at]gmail.com> wrote:
>
>In CPython yes. In IronPython yes: the parts that are compiled into
>machine code are the interpreter, *not user's code*.

WRONG! You are WRONG. At "compile" time, the Python code is compiled to
an intermediate language. At "run" time, the intermediate language (which
is still the user's code, just in another representation) is compiled into
machine language. It is the user's program, not the interpreter.

It's the exact same process that occurs in a C compiler. Most C compilers
translate the C program to an intermediate form before finally converting
it to machine language. The only difference is that, in a C compiler, both
steps occur within the compiler. In IronPython, the two steps are
separated in time. There is no other difference.

>Without that
>step, the interpreter would be running on an interpreter, but that
>doesn't get the user's statement 'a= b+ 1' into registers-- it gets
>'push, push, add, pop' into registers.

You have a fundamental misunderstanding of the compilation process.
--
Tim Roberts, timr[at]probo.com
Providenza & Boekelheide, Inc.
--
http://mail.python.org/mailman/listinfo/python-list


wuwei23 at gmail

Jul 29, 2008, 5:39 AM

Post #23 of 48 (565 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 29, 2:21 pm, castironpi <castiro...@gmail.com> wrote:
> On Jul 28, 5:58 pm, Fuzzyman <fuzzy...@gmail.com> wrote:
> > Well - in IronPython user code gets compiled to in memory assemblies
> > which can be JIT'ed.
>
> I don't believe so.

Uh, you're questioning someone who is not only co-author of a book on
IronPython, but also a developer on one of the first IronPython-based
commercial applications.

I know authorship isn't always a guarantee of correctness, but what
experience do you have with IronPython that makes you so unwilling to
accept the opinion of someone with substantial knowledge of the
subject?

--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 29, 2008, 9:20 PM

Post #24 of 48 (558 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 29, 7:39 am, alex23 <wuwe...@gmail.com> wrote:
> On Jul 29, 2:21 pm, castironpi <castiro...@gmail.com> wrote:
>
> > On Jul 28, 5:58 pm, Fuzzyman <fuzzy...@gmail.com> wrote:
> > > Well - in IronPython user code gets compiled to in memory assemblies
> > > which can be JIT'ed.
>
> > I don't believe so.
>
> Uh, you're questioning someone who is not only co-author of a book on
> IronPython, but also a developer on one of the first IronPython-based
> commercial applications.
>
> I know authorship isn't always a guarantee of correctness, but what
> experience do you have with IronPython that makes you so unwilling to
> accept the opinion of someone with substantial knowledge of the
> subject?

None, no experience, no authority, only the stated premises &
classifications, which I am generally tending to misinterpret. I'm
overstepping my bounds and trying to do it politely. (Some might call
it learning, which yes, though uncustomary, *requires questioning
authorities*, or reinventing.)

Evidently, I have a "fundamental misunderstanding of the compilation
process", which I'm trying to correct by stating what I believe. I'm
trying to elaborate, and I'm meeting with increasingly much detail.
So, perhaps I'll learn something out of this. Until then...

What I know I have is two conflicting, contradictory, inconsistent
beliefs. Maybe I've spent too much time in Python to imagine how a
dynamic language can compile.

This is from 7/22/08, same author:
> I wouldn't say "can't". The current CPython VM does not compile
> code. It COULD. The C#/.NET VM does.

Three big claims here that I breezed right over and didn't believe.

> It COULD.

I'm evidently assuming that if it could, it would.

> The current CPython VM does not compile code.

Therefore it couldn't, or the assumption is wrong. Tim says it is.
And the glaring one--

WHY NOT? Why doesn't CPython do it?

>From 7/18/08, own author:
>>
#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;
<<

I am imagining that every Python implementation has something like
it. If IronPython does not, in particular, not have the 'POP();
TOP();' sequence, then it isn't running on a stack machine. Is the
IronPython code open source, and can someone link to it? I'm not
wading through it from scratch. What does it have instead? Does
dynamic typing still work?

<closing hostile remark>
If you're bluffing, bluff harder; I call. If you're not, I apologize;
teach me something. If you can ask better, teach me that too.
</hostile>
--
http://mail.python.org/mailman/listinfo/python-list


castironpi at gmail

Jul 29, 2008, 9:54 PM

Post #25 of 48 (558 views)
Permalink
Re: interpreter vs. compiled [In reply to]

On Jul 29, 1:46 am, Tim Roberts <t...@probo.com> wrote:
> castironpi <castiro...@gmail.com> wrote:
>
> >In CPython yes.  In IronPython yes:  the parts that are compiled into
> >machine code are the interpreter, *not user's code*.
>
> WRONG!  You are WRONG.  At "compile" time, the Python code is compiled to
> an intermediate language.  At "run" time, the intermediate language (which
> is still the user's code, just in another representation) is compiled into
> machine language.  It is the user's program, not the interpreter.
>
> It's the exact same process that occurs in a C compiler.  Most C compilers
> translate the C program to an intermediate form before finally converting
> it to machine language.  The only difference is that, in a C compiler, both
> steps occur within the compiler.  In IronPython, the two steps are
> separated in time.  There is no other difference.
>
> >Without that
> >step, the interpreter would be running on an interpreter, but that
> >doesn't get the user's statement 'a= b+ 1' into registers-- it gets
> >'push, push, add, pop' into registers.
>
> You have a fundamental misunderstanding of the compilation process.
> --
> Tim Roberts, t...@probo.com
> Providenza & Boekelheide, Inc.

In C, we have:

int x, y;
x= 10;
y= x+ 1;

It translates as, roughly:


8000 .data
7996 ffffffff #x
7992 ffffffff #y
7988 .end data
7984 loadi reg0 7996
7980 loadi reg1 7992
7976 loadi reg2 10
7972 loadi reg3 1
7968 storv reg2 reg0
7964 add reg0 reg1 reg2
7960 storv reg3 reg1


You are telling me that the same thing happens in IronPython. By the
time the instruction pointer gets to 'x= 10', the next 7 instructions
are the ones shown here compiled from C.

CMIIW, but the CPython implementation -does- -not-. Instead, it has,

push 10
stor x
push 1
add
stor y

which each amounts to, to give a rough figure, 5-10 machine
instructions. push 10, for example, with instruction_pointer in reg0:

loadi reg1 4 #add 4 to stack pointer (one word)
add reg0 reg1 reg2
load reg0 reg2
loadi reg2 10 #load ten
stor reg0 reg2 #store at top of stack

And this is all not to mention (i) the extra comparisons in
intobject.h,

#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type)

(ii) the huge case statement just to evaluate add, OR (iii)

a = PyInt_AS_LONG(v);
b = PyInt_AS_LONG(w);

because CPython -does- -not- -know- ahead of time which op it will be
executing, or what addresses (remember __coerce__), it will be
performing the op on. Does not know EVER, not until it gets there.

My point is, CPython takes more than seven steps. My question is,
does IronPython?
--
http://mail.python.org/mailman/listinfo/python-list

First page Previous page 1 2 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.