gfortran/g77+f2py vs gcc+Cython speed comparison

123 views
Skip to first unread message

Ondrej Certik

unread,
Dec 23, 2007, 7:57:32 AM12/23/07
to cytho...@lists.berlios.de, Discussion of Numerical Python, sage-...@googlegroups.com
Hi,

I needed to write 2D Ising model simulation into my school and I
decided to compare the two possible solutions how to do it, so I of
course wrote
it in Python, then rewrote it in Fortran + f2py, and also Cython. What
is better? Read below. :) But for the impatient, I am going to use
Cython, reasons below.

CCing to Cython, numpy (f2py is discussed there), and sage-devel
(there are people there who could be interested in these kinds of
comparisons).

The code is available at:

http://hg.sharesource.org/isingmodel/

How to play with that - just do this (after installing Mercurial):

$ hg clone http://hg.sharesource.org/isingmodel/
[...]
$ cd isingmodel
$ hg up db7dd01cdc26 # just to be sure
that we are talking about the same revision / code
$ make
[...]
$ time python simulate.py
[...]
real 0m2.026s
user 0m1.988s
sys 0m0.020s

This runs Cython code. Then apply this patch to run fortran code instead:

$ hg di
diff -r db7dd01cdc26 simulate.py
--- a/simulate.py Sun Dec 23 02:23:30 2007 +0100
+++ b/simulate.py Sun Dec 23 02:24:33 2007 +0100
@@ -31,8 +31,8 @@ def MC(mu = 1, temp = 2, dim = 20, steps
J=1 #coupling constant
k=1 #Boltzman constant

- #from mcising import mc
- from pyising import mc
+ from mcising import mc
+ #from pyising import mc
B = D1(A)
mc(B, dim, steps, temp, H, mu, J, k)
return D2(B)


And then again (and apply the patch below, otherwise it might not work for you):

$ time python simulate.py
[...]
real 0m3.600s
user 0m3.528s
sys 0m0.052s

So it's a lot slower.

We are comparing many things here - wrappers, my fortran coding skills
vs Cython C code generation and gcc vs gfortran. So I wrote to numpy
mailinglist. First Travis (the author of numpy) suggested:

"
My experience with similar kinds of comparisons is that gnu fortran
compilers are not very good, especially on 2-d problems. Try using a
different fortran compiler to see if speeds improve.
"

Then Pearu (the author of f2py) suggested:

"
Though the problem is 2D, your implementations are essentially
1D. If you would treat the array A as 2D array (and avoid calling
subroutine p) then you would gain some 7% speed up in Fortran.

When using -DF2PY_REPORT_ATEXIT for f2py then a summary
of timings will be printed out about how much time was spent
in Fortran code and how much in the interface. In the given case
I get (nsteps=50000):

Overall time spent in ...
(a) wrapped (Fortran/C) functions : 1962 msec
(b) f2py interface, 60 calls : 0 msec
(c) call-back (Python) functions : 0 msec
(d) f2py call-back interface, 0 calls : 0 msec
(e) wrapped (Fortran/C) functions (acctual) : 1962 msec

that is, most of the time is spent in Fortran function and no time
in wrapper. The conclusion is that the cause of the
difference in timings is not in f2py or cpython generated
interfaces but in Fortran and C codes and/or compilers.

Some idiom used in Fortran code is just slower than in C..
For example, in C code you are doing calculations using
float precision but in Fortran you are forcing double precision.

HTH,
Pearu

PS: Here follows a setup.py file that I used to build the
extension modules instead of the Makefile:

#file: setup.py
def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration
config = Configuration('',parent_package,top_path)
config.add_extension('mcising', sources=['mcising.f'],
define_macros = [('F2PY_REPORT_ATEXIT',1)]
)
#config.add_extension('pyising', sources=['pyising.pyx'])
return config
from numpy.distutils.core import setup
setup(configuration = configuration)
"

and then quickly added

"
When using g77 compiler instead of gfortran, I get a speed
up 4.8 times.

Btw, a line in a if statement of the fortran code
should read `A(p(i,j,N)) = - A(p(i,j,N))`.
"

(btw I have no idea how it could work for me without the A(p(i,j,N)) =
- A(p(i,j,N)) fix, quite embarassing)

So then we discussed it on #sympy IRC:

* Now talking on #sympy
<ondrej> hi pearu, thanks a lot for testing it!
<ondrej> 4.8 speedup, jesus christ. so the gfortran sucks a lot
<pearu> hey ondrej
* ondrej is trying g77
<pearu> gortran has advantage of being Fortran 90 compiler
<ondrej> g77 is depricated in Debian and dead upstram (imho)
<pearu> yes but I guess those guys who are maintaing g77/gfortran,
those do not crunch numbers much;)
<pearu> g77 has a long development history and is well optimized
<ondrej> I fear the fortran is a bad investment for new projects
<ondrej> I know g77 is well optimized, but it's dead
<pearu> gfortran is a write from scratch and is too young
<ondrej> do you think many people still write fortran? I use it just
because g77 was faster than gcc
<pearu> g77 is certainly not dead, scientist use it a lot because of its speed
<ondrej> btw`A(p(i,j,N)) = - A(p(i,j,N))`.
<ondrej> means my fortran code was broken
<ondrej> doesn't it?
<pearu> some think that fortran is a dead language, some use it a lot
because lots of code is written in fortran over several decades
<ondrej> yes
<pearu> yes, it was, I got segfaults because of that
<ondrej> I don't know what to think myself
<pearu> it depends on application
<pearu> if it is a research app then use fortran because of speed
<ondrej> but as you can see, you need to use g77
<ondrej> and not gfortran
<ondrej> (but all Debian is moving to use gfortran)
<pearu> I use gfortran only for f90 code
<ondrej> hm
<pearu> I think Debian is wrong in short term, may be in future
gfortran will be faster, but not at the moment
<ondrej> hm, that's bad
<ondrej> but is someone developing g77?
<pearu> no, I don't think so
<ondrej> debian moved to gfortran, because there are problems with g77
being umaintained
<pearu> but it is a complete Fortran 77 compiler and a very good one
<ondrej> hm. I think when one wants speed, one should use some
comercial compilers
<pearu> probably because new architectures are developed and g77 is
not updated to use their features
<ondrej> and when one wants robustness, it should use a free compiler
that is maintinaed (gfortran)
<pearu> commercial compilers does not mean fast compliers, in general
<ondrej> I didn't try intel, so I don't know how it compares to g77
<pearu> using intel restricts one to be on Intel platform
<ondrej> the g77 doesn't support -fdefault-real-8 for example
<pearu> AMD is daster in floating point that most scientist use
<pearu> why is this flag important, one can always write real*8
<ondrej> indeed, g77 is 1.8s and gcc 2.0s on my comp
<ondrej> as to real*8 - I thought a good strategy is to write real and
let the compiler choose the precision
<pearu> try to use float in fortran as you do in C
<ondrej> ok
<pearu> this will mess up f2py-ing as f2py assumes that real is real*4
<ondrej> yes -
<ondrej> real*4 is float, isn't it?
<pearu> yes
<ondrej> so I'll just use real*4 everywhere
<pearu> yep
<ondrej> ok
<ondrej> btw, I was writing a python script for automatically
converting real*4 to real*8 and back
<ondrej> but it's freaking hard to parse fortran
<ondrej> (I needed to also work with "real", etc)
<ondrej> I only managed it to work in simple cases
<pearu> just do re.sub
<ondrej> it's not that easy
<ondrej> there are constructs like real(something)
<ondrej> that shouldn't be converted
<ondrej> but real T should be converted
<ondrej> etc.
<ondrej> so using real*4 with g77 slowed the code done from 1.8s to 1.9s
<pearu> re.sub should be able to handle these, use cb argument, fo instance
<ondrej> ok
<pearu> you are using random numbers, could this make also a difference
<ondrej> I think it does
<ondrej> (I had to use glibc fast random to speed C up)
<pearu> a, ok, that also explains things
<ondrej> shit, the gfortran is really slow
<ondrej> 3.5s on my comp
<ondrej> no matter which precision
<pearu> try to disable random to see if loops are faster in C or fortran
<ondrej> ok
<ondrej> so gfortran is now 1.3s
<ondrej> and g77 1.04s
* ondrej is trying C
<ondrej> C is 1.05s
<pearu> so gfortran random is slow
<ondrej> yes
<ondrej> g77 random is fast
<ondrej> C random is slower than g77
<ondrej> it depends on the quality of the random generator as well
<ondrej> there are huge differences in that
<pearu> and so gfortran itsel is not too bad
<pearu> :)
<ondrej> but as you can see - there is no point for me to use g77 if I
can achieve the same speed with C
<ondrej> and gfortran is slower than both
<pearu> yep
<ondrej> ok, going to write this to the list
<pearu> can you try ifc
<ondrej> I'll also send it to the Cython guys, they'll like the result. :)
<ondrej> ifc = intel fortran compiler?
<pearu> yes
<ondrej> I like opensource and Debian
<ondrej> I think this clearly shows, that fortran is dead for me. I
think gcc is pretty good too.
<pearu> note that these results are not thanks to pyrex /cpython but
thanks to compilers:)
<pearu> i like to be fair;)
<ondrej> (yes, it's just compilers comparison, not f2py vs Cython/pyrex)
<pearu> yep
<ondrej> but there are two ways a user can choose - either cython+gcc,
or f2py+fortran
<pearu> next time we shoul probably have this discussion inscipy irc
<ondrej> and if he wants to use the most recent default free
compilers, at least I will choose cython+gcc
<pearu> there are more ways, weave, etc etc
<ondrej> I am going to paste this to my email about that
<pearu> ok
<ondrej> (if you are ok with that)
<pearu> ok with me

So, what do you think of that?

Ondrej

mabshoff

unread,
Dec 24, 2007, 4:16:08 PM12/24/07
to sage-devel


On Dec 23, 1:57 pm, "Ondrej Certik" <ond...@certik.cz> wrote:
> Hi,

<SNIP>

> So, what do you think of that?

I am quite shocked that g77 is that far ahead on the performance
curve. I am sure I would have heard about it by now if that was the
general case, but is there any chance your code might hit some corner
case in gfortran? Which gfortran did you use exactly? Does using g95
make a difference?

> Ondrej

Cheers,

Michael

Ondrej Certik

unread,
Dec 24, 2007, 4:37:00 PM12/24/07
to sage-...@googlegroups.com
> I am quite shocked that g77 is that far ahead on the performance
> curve. I am sure I would have heard about it by now if that was the
> general case, but is there any chance your code might hit some corner
> case in gfortran? Which gfortran did you use exactly? Does using g95

$ gfortran --version
GNU Fortran (GCC) 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)
Copyright (C) 2007 Free Software Foundation, Inc.

> make a difference?

As discussed in the IRC session attached in the previous email, the
pure difference is just 1.0 (g77) vs 1.3s (gfortran), so not that big.
One problem was in the random() function, being fast in glibc, slower
in g77 and the slowest in gfortran.

I didn't try g95, as it is not in Debian. I believe in standard tools
and "official" ways of doing things,
which currently is gfortran in Debian. Of course, if there are some
very good reasons, not to follow the
same way as the majority of other people, we can do that, i.e. package
g95 for Debian, recompile
debian packages with g95, instead of gfortran (currently Debian uses
g77, but it's moving to gfortran),
find a way how to ship both binary packages in Debian (compiled with
both gfortran and g95) etc.

But I am not really looking into speeding up this particular code, but
just finding ways what people
use and are going to use. Fortran will definitely not die (at least
not soon), but I still feel that C
is much more widespread language, with comparable speed.

Ondrej

mabshoff

unread,
Dec 24, 2007, 4:47:19 PM12/24/07
to sage-devel

Hi Ondrej,

On Dec 24, 10:37 pm, "Ondrej Certik" <ond...@certik.cz> wrote:
> > I am quite shocked that g77 is that far ahead on the performance
> > curve. I am sure I would have heard about it by now if that was the
> > general case, but is there any chance your code might hit some corner
> > case in gfortran? Which gfortran did you use exactly? Does using g95
>
> $ gfortran --version
> GNU Fortran (GCC) 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)
> Copyright (C) 2007 Free Software Foundation, Inc.

Ok, that seems reasonably current ;)

> > make a difference?
>
> As discussed in the IRC session attached in the previous email, the
> pure difference is just 1.0 (g77) vs 1.3s (gfortran), so not that big.
> One problem was in the random() function, being fast in glibc, slower
> in g77 and the slowest in gfortran.

Ok, I over read that detail, the mail was pretty long, but thanks for
the clarification.

> I didn't try g95, as it is not in Debian. I believe in standard tools
> and "official" ways of doing things,
> which currently is gfortran in Debian. Of course, if there are some
> very good reasons, not to follow the
> same way as the majority of other people, we can do that, i.e. package
> g95 for Debian, recompile
> debian packages with g95, instead of gfortran (currently Debian uses
> g77, but it's moving to gfortran),
> find a way how to ship both binary packages in Debian (compiled with
> both gfortran and g95) etc.
>
> But I am not really looking into speeding up this particular code, but
> just finding ways what people
> use and are going to use. Fortran will definitely not die (at least
> not soon),

I consider that unlikely to happen, but I certainly won't be sad when
the use of Fortran were to decline over the next couple years.

> but I still feel that C
> is much more widespread language, with comparable speed.
>
> Ondrej

Cheers,

Michael

Ondrej Certik

unread,
Dec 24, 2007, 4:54:29 PM12/24/07
to sage-...@googlegroups.com
> > But I am not really looking into speeding up this particular code, but
> > just finding ways what people
> > use and are going to use. Fortran will definitely not die (at least
> > not soon),
>
> I consider that unlikely to happen, but I certainly won't be sad when
> the use of Fortran were to decline over the next couple years.

I won't be sad either.

Ondrej

Reply all
Reply to author
Forward
0 new messages