Python Front-end to GCC


P

Philip Herron

Hey,

I've been working on GCCPY since roughly november 2009 at least in its
concept. It was announced as a Gsoc 2010 project and also a Gsoc 2011
project. I was mentored by Ian Taylor who has been an extremely big
influence on my software development carrer.

Gccpy is an Ahead of time implementation of Python ontop of GCC. So it
works as you would expect with a traditional compiler such as GCC to
compile C code. Or G++ to compile C++ etc.

Whats interesting and deserves a significant mention is my work is
heavily inspired by Paul Biggar's phd thesis on optimizing dynamic
languages and his work on PHC a ahead of time php compiler. I've had
so many ups and down in this project and i need to thank Andi Hellmund
for his contributions to the project.
http://paulbiggar.com/research/#phd-dissertation

The project has taken so many years as an in my spare time project to
get to this point. I for example its taken me so long simply to
understand a stabilise the core fundamentals for the compiler and how
it could all work.

The release can be found here. I will probably rename the tag to the
milestone (lucy) later on.
https://github.com/redbrain/gccpy/releases/tag/v0.1-24
(Lucy is our dog btw, German Shepard (6 years young) loves to lick
your face off :) )

Documentation can be found http://gcc.gnu.org/wiki/PythonFrontEnd.
(Although this is sparse partialy on purpose since i do not wan't
people thinking this is by any means ready to compile real python
applications)

I've found some good success with this project in compiling python
though its largely unknown to the world simply because i am nervous of
the compiler and more specifically the python compiler world.

But at least to me there is at least to me an un-answered question in
current compiler implementations. AOT vs Jit.

Is a jit implementation of a language (not just python) better than
traditional ahead of time compilation.

What i can say is ahead of time at least strips out the crap needed
for the users code to be run. As in people are forgetting the basics
of how a computer works in my opinion when it comes to making code run
faster. Simply need to reduce the number of instructions that need to
be executed in order to preform what needs to be done. Its not about
Jit and bla bla keyword llvm keyword instruction scheduling keyword
bla.

I could go into the arguments but i feel i should let the project
speak for itself its very immature so you really cant compare it to
anything like it but it does compile little bits and bobs fairly well
but there is much more work needed.

There is nothing at steak, its simply an idea provoked from a great
phd thesis and i want to see how it would work out. I don't get funded
of paid. I love working on compilers and languages but i don't have a
day job doing it so its my little pet to open source i believe its at
least worth some research.

I would really like to hear the feedback good and bad. I can't
describe how much work i've put into this and how much persistence
I've had to have in light of recent reddit threads talking about my
project.

I have so many people to thank to get to this point! Namely Ian
Taylor, Paul Biggar, Andi Hellmund, Cyril Roelandt Robert Bradshaw,
PyBelfast, and the Linux Outlaws community. I really couldn't have got
to this point in my life without the help of these people!

Thanks!

--Phil
 
Ad

Advertisements

V

victorgarcianet

I've been working on GCCPY since roughly november 2009 at least in its
concept. It was announced as a Gsoc 2010 project and also a Gsoc 2011
project. I was mentored by Ian Taylor who has been an extremely big
influence on my software development carrer.
Cool!

Documentation can be found http://gcc.gnu.org/wiki/PythonFrontEnd.
(Although this is sparse partialy on purpose since i do not wan't
people thinking this is by any means ready to compile real python
applications)

Is there any document describing what it can already compile and, if possible, showing some benchmarks?
But at least to me there is at least to me an un-answered question in
current compiler implementations. AOT vs Jit.

Is a jit implementation of a language (not just python) better than
traditional ahead of time compilation.

What i can say is ahead of time at least strips out the crap needed
for the users code to be run. As in people are forgetting the basics
of how a computer works in my opinion when it comes to making code run
faster. Simply need to reduce the number of instructions that need to
be executed in order to preform what needs to be done. Its not about
Jit and bla bla keyword llvm keyword instruction scheduling keyword
bla.

Maybe a less agressive tone (and a lot more research before going into sweeping statements that do nothing to further your own project) could result in a better level of discussion?
I could go into the arguments but i feel i should let the project
speak for itself its very immature so you really cant compare it to
anything like it but it does compile little bits and bobs fairly well
but there is much more work needed.

Can you compare it to Nuitka (http://nuitka.net/), ShedSkin (http://nuitka.net/) and Pythran (http://pythonhosted.org/pythran/) when you think it's mature enough? These projects have test suits you can borrow to chart you progress along the full-language support road.

It'd be good to find a place for your project on http://compilers.pydata.org/ , as soon as you better describe its workings.
There is nothing at steak, its simply an idea provoked from a great
phd thesis and i want to see how it would work out. I don't get funded
of paid. I love working on compilers and languages but i don't have a
day job doing it so its my little pet to open source i believe its at
least worth some research.

It's very interesting indeed. Congratulations and thank you for your work.

Victor
 
M

Mark Janssen

Gccpy is an Ahead of time implementation of Python ontop of GCC. So it
works as you would expect with a traditional compiler such as GCC to
compile C code. Or G++ to compile C++ etc.

That is amazing. I was just talking about how someone should make a
front-end to GCC on this list a couple of months ago. Awesome!
Documentation can be found http://gcc.gnu.org/wiki/PythonFrontEnd.
(Although this is sparse partialy on purpose since i do not wan't
people thinking this is by any means ready to compile real python
applications)

What's missing?
I've found some good success with this project in compiling python
though its largely unknown to the world simply because i am nervous of
the compiler and more specifically the python compiler world.

But at least to me there is at least to me an un-answered question in
current compiler implementations. AOT vs Jit.

Is a jit implementation of a language (not just python) better than
traditional ahead of time compilation.

Not at all. The value of jit compilation, I believe, is purely for
the dynamic functionality that it allows. AOT compilation will never
allow that, but in return you get massive performance and runtime-size
gains (that is, you don't need a massive interpreter environment
anymore!) If your compiler produces an executable program without the
need for the python interpreter environment: Two major wins.
What i can say is ahead of time at least strips out the crap needed
for the users code to be run. As in people are forgetting the basics
of how a computer works in my opinion when it comes to making code run
faster.
Agreed.

I could go into the arguments but i feel i should let the project
speak for itself its very immature so you really cant compare it to
anything like it but it does compile little bits and bobs fairly well
but there is much more work needed.

I wish I had the resources to try it myself, but would love to see
some performance numbers (say factorizations, or bubble-sorts, etc).
Also runtime executable sizes.

I would really like to hear the feedback good and bad. I can't
describe how much work i've put into this and how much persistence
I've had to have in light of recent reddit threads talking about my
project.

Please reference threads in question, would like to see the issues raised.
 
S

Steven D'Aprano

On Sun, 20 Oct 2013 20:35:03 -0700, Mark Janssen wrote:

[Attribution to the original post has been lost]
Not at all. The value of jit compilation, I believe, is purely for the
dynamic functionality that it allows. AOT compilation will never allow
that, but in return you get massive performance and runtime-size gains

On the contrary, you have that backwards. An optimizing JIT compiler can
often produce much more efficient, heavily optimized code than a static
AOT compiler, and at the very least they can optimize different things
than a static compiler can. This is why very few people think that, in
the long run, Nuitka can be as fast as PyPy, and why PyPy's ultimate aim
to be "faster than C" is not moonbeams:

http://morepypy.blogspot.com.au/2011/02/pypy-faster-than-c-on-carefully-crafted.html

http://morepypy.blogspot.com.au/2011/08/pypy-is-faster-than-c-again-string.html


See here for a discussion on what JIT compilers can do which static
compilers can't:

http://en.wikipedia.org/wiki/Just-in-time_compilation


Of course, the disadvantage of a JIT compiler is that there's a certain
amount of runtime overhead: it takes time to analyse the running code,
and more time to compile it on the fly. This is why, for example, PyPy
likely won't be as fast for really short-running scripts as a static
compiler could be. Again, see the Wikipedia article.

JIT compilation is really about optimization, which is why languages like
Java and .NET which could easily be compiled to machine code at compile
time generally use an intermediate bytecode and a JIT compiler instead.
They're not doing it for dynamism since they aren't dynamic languages.
It's a way of generating more aggressive (i.e. better but harder)
optimizations based on information only available at runtime.
 
O

Oscar Benjamin

On Sun, 20 Oct 2013 20:35:03 -0700, Mark Janssen wrote:

[Attribution to the original post has been lost]
Not at all. The value of jit compilation, I believe, is purely for the
dynamic functionality that it allows. AOT compilation will never allow
that, but in return you get massive performance and runtime-size gains

On the contrary, you have that backwards. An optimizing JIT compiler can
often produce much more efficient, heavily optimized code than a static
AOT compiler, and at the very least they can optimize different things
than a static compiler can. This is why very few people think that, in
the long run, Nuitka can be as fast as PyPy, and why PyPy's ultimate aim
to be "faster than C" is not moonbeams:

That may be true but both the examples below are spurious at best. A
decent AOT compiler would reduce both programs to the NULL program as
noted by haypo:
http://morepypy.blogspot.co.uk/2011...howComment=1297205903746#c2530451800553246683

I just modified the add() example so that none of the operations can
be entirely optimised away:

def main():
i = 0
a = 0.0
b = 0.0
while i < 1000000000:
a += 1.0
b += add(a, a)
i += 1
print(b)

Similarly for the C version:

#include <stdio.h>

double add(double a, double b);

int main()
{
int i = 0;
double a = 0;
double b = 0;
while (i < 1000000000) {
a += 1.0;
b += add(a, a);
i++;
}
printf("%f", b);
}

My timings:

$ gcc -O3 x.c y.c
$ time ./a.exe
1000000000134218000.000000
real 0m5.609s
user 0m0.015s
sys 0m0.000s
$ time pypy y.py
1.00000000013e+18

real 0m9.891s
user 0m0.060s
sys 0m0.061s

So the pypy version takes twice as long to run this. That's impressive
but it's not "faster than C".

I also compared a script that uses intensive decimal computation run
under CPython 3.3 and PyPy 2.1 (pyver 2.7). This is essentially a
comparison between the C implementation of the decimal module and
pypy's jit'd optimisation of the pure Python module. CPython 3.3 takes
10 seconds and PyPy 2.1 takes 45 seconds. Again that's impressive (a
lot of work went into making the C implementation of the decimal
module as fast as it is) but it's not faster than C.

I don't mean to criticise PyPy. I've just tested it and I am impressed
and I think I'll definitely try and use it where possible. I do think
that some of the marketing there is misleading though.


Oscar
 
P

Philip Herron

Hey all,

Thanks, i've been working on this basically on my own 95% of the compiler is all my code, in my spare time. Its been fairly scary all of this for me. I personally find this as a real source of interest to really demystify compilers and really what Jit compilation really is under the hood.

For example if your really interested to see what jit compilation really is(not magic) look at:
http://compilers.iecc.com/comparch/article/10-03-063

And i really believe in this project. Though i really want to say away fromcomparing my project to any others out there. As they are much more maturethan mine.

For example its only a few commits back your successfully able to compile:

import sys

So i think its fairly unfair comparisons could get me into trouble. Whats taken so long is i do not reuse the python runtime like the others. Other projects do this to maintain computability mostly. But i wanted to test doingthis entirely from scratch partly for my own interest and that the python runtime was designed for an interpreter, not compilers at least ahead of time.

Its interesting a few things come up what about:

exec and eval. I didn't really have a good answer for this at my talk at PYCon IE 2013 but i am going to say no. I am not going to implement these. Partly because eval and exec at least to me are mostly from developing interpreters as a debugging exercise so the test doesn't have to invoke the program properly and feed in strings to interpret at least thats what i have done in the past with an virtual machine i wrote before gccpy.

I think anything you look up on eval and exec you shouldn't use them in production code as it could lead to a lot of issues. I can see their use in quick dirty uses but i don't think they really are part of the python language in my opinion its just some builtin functions that you can invoke. Another issue i had was:

class myClass: pass

I currently don't allow this but i've re thought this and i am going to tryand implement this properly before i had a really complicated to pass to quess the type of a struct but i realise currently with how things work thismay not be the case.

As a personal comment i think this is kind of funny as why not use a dict. But i can see the use for it now, and i want to implement it.

What i will say is gccpy is moving along with each milestone i will achieveover the course of the first half of 2014 i reckon i could at least compile half of a decnt python test suite. Its taken me so long to get used to the GCC code base and how i want to implement things i've re-wrote the runtime and the compiler probably at least 4 times and i am going to rewrite partof the runtime today for the next week or so. I think tis a worth while project.

I don't think this will ever be on par with PyPy or CPython as professionalas those projects are i really respect their work i mean i look up to them(loads) i am just a guy who likes compilers and it isnt my day job i don'tget paid for this i just enjoy the challenge and i hope you understand that this is my baby and i am very protective of my project :).

I hope in a few months when i start compiling testsuiites i will publish benchmarks what i will say is it looks pretty good right now only 1 case so far (that i have tested) where i am not faster than CPython and its only because i havent been compiling the runtime library with correct CFLAGS like -O2 etc i wasnt passing anything another is i have tonnnes of debugging malloc all over the show slowing it down because i need to rewrite part of the runtime so yeah. I've been fighting GCC for 4 years now i am fighting my own code ;).

Final note i am not saying JIT is bad or not the way to do things i personally think this question isn't answered and i can see the case for it there are down sides that jit people wont talk about.

The complexity of maintaining a j it in project is probably the main one and optimisations at runtime make it even more mental as they are hard to do is an under statement never mind they aren't as common as you would want tobelieve outside of target specifics which gcc already knows (-mtune*). I do believe JIT is the way forward but i think something in languages needs to really be designed from that perspective and maybe even cpu's to help with some kind of instructions to help maintain a destination between runtime and user code or something (making tail call optimisations easier on dynamic languages) maybe?

Thanks.
 
Ad

Advertisements

M

Mark Janssen

On Sun, 20 Oct 2013 20:35:03 -0700, Mark Janssen wrote:

[Attribution to the original post has been lost]
Not at all. The value of jit compilation, I believe, is purely for the
dynamic functionality that it allows. AOT compilation will never allow
that, but in return you get massive performance and runtime-size gains

On the contrary, you have that backwards. An optimizing JIT compiler can
often produce much more efficient, heavily optimized code than a static
AOT compiler,

This is horseshit.
and at the very least they can optimize different things
than a static compiler can.

Okay sure. But now you've watered down your claim that's it's not
saying much of anything.
This is why very few people think that, in
the long run, Nuitka can be as fast as PyPy, and why PyPy's ultimate aim
to be "faster than C" is not moonbeams:

It is moonbeams, but that's a good thing. I think you don't
understand how computers work, Steven.
In any event, PyPy is a great project for those who want experiment
with compiler and language design.
JIT compilation is really about optimization,
No.

which is why languages like
Java and .NET which could easily be compiled to machine code at compile
time generally use an intermediate bytecode and a JIT compiler instead.
They're not doing it for dynamism since they aren't dynamic languages.
It's a way of generating more aggressive (i.e. better but harder)
optimizations based on information only available at runtime.

This must is true, but not for reasons you understand.
 
M

Mark Janssen

Thanks, i've been working on this basically on my own 95% of the compileris all my code, in my spare time. Its been fairly scary all of this for me.. I personally find this as a real source of interest to really demystify compilers and really what Jit compilation really is under the hood.

So I'm curious, not having looked at your code, are you just
translating python code into C code to make your front-end to gcc?
Like converting "[1,2,3]" into a C linked-list data structure and
making 1 an int (or BigNum?)?
 
N

Ned Batchelder

On Sun, 20 Oct 2013 20:35:03 -0700, Mark Janssen wrote:

[Attribution to the original post has been lost]
Is a jit implementation of a language (not just python) better than
traditional ahead of time compilation.
Not at all. The value of jit compilation, I believe, is purely for the
dynamic functionality that it allows. AOT compilation will never allow
that, but in return you get massive performance and runtime-size gains
On the contrary, you have that backwards. An optimizing JIT compiler can
often produce much more efficient, heavily optimized code than a static
AOT compiler,
This is horseshit.

Surely we can discuss this without resorting to swearing.
Okay sure. But now you've watered down your claim that's it's not
saying much of anything.

It is moonbeams, but that's a good thing. I think you don't
understand how computers work, Steven.
I think Steven has earned the benefit of the doubt when it comes to
understanding computer. Did you read the links he provided? Do you
believe that author also doesn't understand how computers work?

Mark, disagreement doesn't have to lead to ad-hominem attacks. If you
think Steven is wrong about what JIT compilers can do, please explain.
Simply calling his statements horseshit and saying he doesn't understand
computers is not a rebuttal.
In any event, PyPy is a great project for those who want experiment
with compiler and language design.

No.

Please tell us what JIT compilation is about.
This must is true, but not for reasons you understand.
Again, a statement with no supporting information.

*sigh*

If someone says something that seems wrong to you, there are a number of
possibilities: 1) you are wrong, 2) they are wrong, or 3) you haven't
understood each other yet. Please have the humility to at least
consider option 3 first.

--Ned.
 
P

Philip Herron

Thanks, i've been working on this basically on my own 95% of the compiler is all my code, in my spare time. Its been fairly scary all of this for me. I personally find this as a real source of interest to really demystifycompilers and really what Jit compilation really is under the hood.



So I'm curious, not having looked at your code, are you just

translating python code into C code to make your front-end to gcc?

Like converting "[1,2,3]" into a C linked-list data structure and

making 1 an int (or BigNum?)?



--

MarkJ

Tacoma, Washington

No its not like those 'compilers' i dont really agree with a compiler generating C/C++ and saying its producing native code. I dont really believe itstruely within the statement. Compilers that do that tend to put in alot oftype saftey code and debugging internals at a high level to get things working in other projects i am not saying python compilers here i havent analysed enough to say this.

What i mean as a front-end is jut like GCC G++ gccgo gfortran it all works the same each of these are front-ends you can pass all those mental gcc options like -O3 -mtune -fblabla. it is implemented as part of gcc and you can'bootstrap python'. You can -fdump-tree-all etc.

What i can say is jit compilation is really mistified' in a big way when itcomes to projects like pypy when its implemented in python how can it callmmap to make an executable memory block etc. When it comes to compilation i think it gets fairly mistified in the python compiler community even more..
 
M

Mark Janssen

No its not like those 'compilers' i dont really agree with a compiler generating C/C++ and saying its producing native code. I dont really believe its truely within the statement. Compilers that do that tend to put in alot of type saftey code and debugging internals at a high level to get things working in other projects i am not saying python compilers here i havent analysed enough to say this.

Hmm, well what I'd personally find interesting from a computer science
point of view is a app that will take a language specification in BNF
(complete with keywords and all) and output C code which is then
compiled to an executable as normal. This is how a front-end should
be designed. A middle-layer for translating common language elements
like lists, sets, etc, could make it easy.
 
Ad

Advertisements

S

Steven D'Aprano

That may be true but both the examples below are spurious at best. A
decent AOT compiler would reduce both programs to the NULL program as
noted by haypo:
http://morepypy.blogspot.co.uk/2011/02/pypy-faster-than-c-on-carefully-
crafted.html?showComment=1297205903746#c2530451800553246683

Are you suggesting that gcc is not a decent compiler? If "optimize away
to the null program" is such an obvious thing to do, why doesn't the most
popular C compiler in the [FOSS] world do it?


[...]
So the pypy version takes twice as long to run this. That's impressive
but it's not "faster than C".

Nobody is saying that PyPy is *generally* capable of making any arbitrary
piece of code run as fast as hand-written C code. You'll notice that the
PyPy posts are described as *carefully crafted* examples.

I believe that, realistically, PyPy has potential to bring Python into
Java and .Net territories, namely to run typical benchmarks within an
order of magnitude of C speeds on the same benchmarks. C is a very hard
target to beat, because vanilla C code does *so little* compared to other
languages: no garbage collection, no runtime dynamism, very little
polymorphism. So benchmarking simple algorithms plays to C's strengths,
while ignoring C's weaknesses.
 
R

rusi

Surely we can discuss this without resorting to swearing.

Thanks Ned for the intervention.
It is good to have 'interesting' and even 'hot' discussions.
Beyond a point they remain hot but not interesting
 
P

Piet van Oostrum

Mark Janssen said:
Hmm, well what I'd personally find interesting from a computer science
point of view is a app that will take a language specification in BNF
(complete with keywords and all) and output C code which is then
compiled to an executable as normal. This is how a front-end should
be designed. A middle-layer for translating common language elements
like lists, sets, etc, could make it easy.

A language specification in BNF is just syntax. It doesn't say anything
about semantics. So how could this be used to produce executable C code
for a program? BNF is used to produce parsers. But a parser isn't
sufficient.
 
M

Mark Janssen

A language specification in BNF is just syntax. It doesn't say anything
about semantics. So how could this be used to produce executable C code
for a program? BNF is used to produce parsers. But a parser isn't
sufficient.

A C program is just syntax also. How does the compiler generate
executable machine code? Extrapolate into a Python front-end to C.
 
D

Dave Angel

A C program is just syntax also. How does the compiler generate
executable machine code? Extrapolate into a Python front-end to C.

Did you even read the paragraph you quoted above? The BNF specification
does NOT completely describe a language, it only defines its syntax. So
if the only thing you knew about C was its BNF, you could certainly not
write a C compiler. And neither could anyone else. Fortunately for the
C community, the language specification included much more than a BNF
grammar. At a minimum, you have to specify both the syntax and the
semantics.

All that has nothing to do with an actual program written in an
actually defined language, whether C or Python.
 
Ad

Advertisements

S

Steven D'Aprano

A C program is just syntax also. How does the compiler generate
executable machine code? Extrapolate into a Python front-end to C.

Like every other language, C programs are certainly not *just* syntax.
Here is some syntax:

&foo bar^ :=

What machine code should be produced? Right now, you should be saying
"How the hell do I know? What does that line of code *do*???" and you
would be right to ask that question.

Syntax on its own doesn't mean anything. You also need to know the
*semantics* of the code, in other words, *what it means*. That knowledge
is inherent to the compiler: a C compiler "understands" what C code
means, a Pascal compiler "understands" Pascal code, a Forth compiler
"understands" Forth.

Merely parsing code doesn't capture that understanding. Parsing a line
like "foo <= bar" will give you something like this:

NAME "foo"
OPERATOR "<="
NAME "bar"
END_LINE

What does the operator "<=" actually do? What does "foo" represent? Is it
a variable, a constant, a global, a local, something else? What are the
rules for deciding whether a variable is in the local scope, a global
scope, or something else? Does the language even have scopes?
 
A

Antoine Pitrou

Philip Herron said:
Its interesting a few things come up what about:

exec and eval. I didn't really have a good answer for this at my talk at
PYCon IE 2013 but i am going to say no. I am
not going to implement these. Partly because eval and exec at least to me are mostly from developing
interpreters as a debugging exercise so the test doesn't have to invoke
the program properly and feed in
strings to interpret at least thats what i have done in the past with an
virtual machine i wrote before gccpy.

If you don't implement exec() and eval() then people won't be able to use
namedtuples, which are a common datatype factory.

As for the rest: well, good luck writing an AOT compiler producing
interesting results on average *pure* Python code. It's already been tried
a number of times, and has generally failed. Cython mitigates the issue by
exposing a superset of Python (including type hints, etc.).

Regards

Antoine.
 
P

Philip Herron

PYCon IE 2013 but i am going to say no. I am


are mostly from developing


the program properly and feed in


virtual machine i wrote before gccpy.



If you don't implement exec() and eval() then people won't be able to use

namedtuples, which are a common datatype factory.



As for the rest: well, good luck writing an AOT compiler producing

interesting results on average *pure* Python code. It's already been tried

a number of times, and has generally failed. Cython mitigates the issue by

exposing a superset of Python (including type hints, etc.).



Regards



Antoine.
Thanks for that interesting example, i haven't looked into how its implemented but on initially looking at this is am nearly sure i can implement thiswithout using exec or eval. I've found this a lot in implementing my run time. Exec and eval at least to me in the past I've used them as debug hooksinto a toy virtual machine i wrote i don't particularly think they are part of a language nor should people really use them.

Thanks
 
Ad

Advertisements

O

Oscar Benjamin

That may be true but both the examples below are spurious at best. A
decent AOT compiler would reduce both programs to the NULL program as
noted by haypo:
http://morepypy.blogspot.co.uk/2011/02/pypy-faster-than-c-on-carefully-
crafted.html?showComment=1297205903746#c2530451800553246683

Are you suggesting that gcc is not a decent compiler?
No.

If "optimize away
to the null program" is such an obvious thing to do, why doesn't the most
popular C compiler in the [FOSS] world do it?

It does if you pass the appropriate optimisation setting (as shown in
haypo's comment). I should have been clearer.

gcc compiles programs in two phases: compilation and linking.
Compilation creates the object files x.o and y.o from x.c and y.c.
Linking creates the output binary a.exe from x.o and y.o. The -O3
optimisation setting used in the blog post enables optimisation in the
compilation phase. However each .c file is compiled independently so
because the add() function is defined in x.c and called in y.c the
compiler is unable to inline it. It also can't remove it as dead code
because although it knows that the return value isn't used it doesn't
know if the call has side effects.

You might think it's silly that gcc can't optimise across source files
and if so you're right because actually it can if you enable link time
optimisation with the -flto flag as described by haypo. So if I do
that with the code from the blog post I get (using mingw gcc 4.7.2 on
Windows):

$ cat x.c
double add(double a, double b)
{
return a + b;
}
$ cat y.c
double add(double a, double b);

int main()
{
int i = 0;
double a = 0;
while (i < 1000000000) {
a += 1.0;
add(a, a);
i++;
}
}
$ gcc -O3 -flto x.c y.c
$ time ./a.exe

real 0m0.063s
user 0m0.015s
sys 0m0.000s
$ time ./a.exe # warm cache

real 0m0.016s
user 0m0.015s
sys 0m0.015s

So gcc can optimise this all the way to the null program which takes
15ms to run (that's 600 times faster than pypy).

Note that even if pypy could optimise it all the way to the null
program it would still be 10 times slower than C's null program:

$ touch null.py
$ time pypy null.py

real 0m0.188s
user 0m0.076s
sys 0m0.046s
$ time pypy null.py # warm cache

real 0m0.157s
user 0m0.060s
sys 0m0.030s
[...]
So the pypy version takes twice as long to run this. That's impressive
but it's not "faster than C".

(Actually if I enable -flts with that example the C version runs 6-7
times faster due to inlining.)
Nobody is saying that PyPy is *generally* capable of making any arbitrary
piece of code run as fast as hand-written C code. You'll notice that the
PyPy posts are described as *carefully crafted* examples.

They are more than carefully crafted. They are useless and misleading.
It's reasonable to contrive of a simple CPU-intensive programming
problem for benchmarking. But the program should do *something* even
if it is contrived. Both programs here consist *entirely* of dead
code. Yes it's reasonable for the pypy devs to test things like this
during development. No it's not reasonable to showcase this as an
example of the potential for pypy to speed up any useful computation.
I believe that, realistically, PyPy has potential to bring Python into
Java and .Net territories, namely to run typical benchmarks within an
order of magnitude of C speeds on the same benchmarks. C is a very hard
target to beat, because vanilla C code does *so little* compared to other
languages: no garbage collection, no runtime dynamism, very little
polymorphism. So benchmarking simple algorithms plays to C's strengths,
while ignoring C's weaknesses.

As I said I don't want to criticise PyPy. I've just started using it
and I it is impressive. However both of those blog posts are
misleading. Not only that but the authors must know exactly why they
are misleading. Because of that I will take any other claims with a
big pinch of salt in future.


Oscar
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top