Tell me more ×
Computational Science Stack Exchange is a question and answer site for scientists using computers to solve scientific problems. It's 100% free, no registration required.

In my computational science PhD program, we are working almost exclusively in C++ and Fortran. It seems like some professors prefer one over the other. I am wondering which one is 'better' or if one is better than the other in a certain circumstance.

share|improve this question
8  
A mix of a high and low level language is better than exclusively using either, in my opinion. E.g. I use Python + C++. – Faheem Mitha Dec 8 '11 at 7:22

11 Answers

up vote 28 down vote accepted

As so often, the choice depends on (1) the problem you are trying to solve, (2) the skills you have, and (3) the people you work with (unless it's a solo project). I'll leave (3) aside for the moment because it depends on everyone's individual situation.

Problem dependence: Fortran excels at array processing. If your problem can be described in terms of simple data structures and in particular arrays, Fortran is well adapted. Fortran programmers end up using arrays even in non-obvious cases (e.g. for representing graphs). C++ is better suited for complex and highly dynamic data structures.

Skill dependence: it takes a lot more programming experience to write good C++ programs than to write good Fortran programs. If you start out with little programming experience and only have so much time to learn that aspect of your job, you probably get a better return on investment learning Fortran than learning C++. Assuming, of course, that your problem is suited to Fortran.

However, there's more to programming than just Fortran and C++. I'd recommend to anyone going into computational science to start with a dynamic high-level language such as Python. Always remember that your time is more valuable than CPU time!

share|improve this answer
2  
"Always remember that your time is more valuable than CPU time!" As someone who works in HPC I disagree with that part; everything else is spot on. – Levi Morrison Mar 7 at 16:32

I think that both C++ and Fortran are good enough and work well.

However I think that Fortran is better for numeric scientific computing, for algorithms that can be expressed using arrays and don't need other sophisticated data structures, so in fields like finite differences/elements, PDE solvers, electronic structure calculations. Fortran is a domain specific language. In particular I think that it is easier to write fast programs in Fortran than in C++, by a scientist (not necessarily a computer science expert).

C++ is a general purpose language, so one can express any algorithm in it, and it is most definitely better for algorithms that can't be expressed using arrays, from HPC field probably some graphs, mesh generators, symbolic manipulation and so on.

It is also possible to write array algorithms in C++, but in my experience, it requires much more computer science knowledge and in general more work (i.e. one needs to create or reuse classes for array manipulation, and handle memory management by hand or using some library like Teuchos from Trilinos). Non-experts tend to write pretty good Fortran programs, but horrible C++ programs (talking from my own experience).

Disclaimer: I personally like Fortran a lot and I prefer it over C++ for numeric computing. I have spent over 2 years of programming in C++ daily, and almost a year programming in modern Fortran daily (in finite elements area). I use Python and Cython a lot too.

share|improve this answer
This is a very general question, so I am answering also in general terms. I am aware that other people will have different opinions. – Ondřej Čertík Dec 8 '11 at 6:36
One up for the first answer being balanced. I think C++ and Fortran are by far not the only possibilities in contemporary HPC. I think it is good to know the strength and weak spots when you decide for Fortran, C++ or Python (or whatever you like). I have seen 20.000 lines of Fortran in one single file, organicly grown over some decades. I personally would not use for anything other than isolated heavy array computing. Not even for anything related to output. So far for a biased comment. – Martin Dec 8 '11 at 8:16
4  
I couldn't disagree with this response more. Our finite element code would not have been possible to write in Fortran. In fact, it started 15 years ago as a mix of plain C and Fortran (the latter being for the numerically intensive parts of the method), and it gradually moved to pure C and then to C++ over the course of several years. The code got consistently shorter, faster, and easier to understand, and it was more capable after each iteration. I agree with others that point out that C++ gives you plenty of rope to shoot yourself with. Pick the language you're most comfortable with. – Bill Barth Dec 8 '11 at 14:18
3  
Bill, did you use modern Fortran (90 and later additions?). This is very important (I should have been more explicit in my answer about this). Of course, "20.000 lines of Fortran", or f77 usually is not better than well written C++. – Ondřej Čertík Dec 13 '11 at 6:12
3  
@WolfgangBangerth, see for example Phaml (math.nist.gov/phaml) for a Fortran implementation of pretty much everything that you mentioned. – Ondřej Čertík Apr 22 '12 at 4:04
show 1 more comment

My approach has been to use C++ for everything but computational kernels, which are usually best written in assembly; this buys you all of the performance of the traditional HPC approach but allows you to simplify the interface, e.g., by overloading computational kernels like SGEMM/DGEMM/CGEMM/ZGEMM into a single routine, say Gemm. Clearly the abstraction level can be raised much higher by avoiding raw pointers and switching to opaque classes, but it is a nice first step.

I find the largest downside of C++ to overwhelmingly be the increase in compilation time, but, in my experience, the savings in development time more than make up for it. Another downside is that vendor C++ compilers tend to have more bugs than vendor C and Fortran compilers. In the past year, I think I have run into nearly ten bugs in C++ compilers.

With all of that said, I think that the undoing of scientific packages written in low-level languages (and Fortran) is the reluctance to expose convenient interfaces for sophisticated data structures: most people are satisfied with the Fortran BLAS interface, as it only requires pointers and leading dimensions to describe matrices, but few people would argue that the usual 40-integer Fortran sparse-direct solver interface is anything close to convenient (cf. UHM, SuperLU, PETSc, and Trilinos).

In summary, I argue for using assembly for low-level computational kernels, but higher level languages for everything else, especially when operating on non-trivial data structures.

Note that this post resulted in this comparison of the performance of C and Fortran on the kernel $y := \alpha x + y$.

share|improve this answer
2  
Why wouldn't you trust a standard C compiler with appropriate optimization enabled for the purpose of compiling small kernels? At that level of code size and complexity the difference in what a compiler could pull out of it is unclear. – Peter Brune Dec 9 '11 at 5:13
1  
I have talked with several people who have told me that, even with appropriate restrict usage, their Fortran was still faster than their C and/or C++ code for some operation like an explicit matrix transpose. I'm not saying that it's impossible to make the C or C++ code as fast, but that the Fortran compiler tends to do a better job. – Jack Poulson Dec 9 '11 at 5:58
I have the same experience with the "restrict" keyword (my simple Fortran code was always a little faster). But my expertise is limited, and I simply don't have time to invest into understanding the generated assembly from gcc. So I simply use Fortran, it's simple and it's fast. – Ondřej Čertík Dec 13 '11 at 6:15
@JackPoulson: The compiler argument is something I hear quite a bit from the Fortran community. Unfortunately, most compilers, e.g. gcc or ifc/icc, use different language front-ends for the same back-end. The machinery doing the optimization and code generation is identical and therefore the differences in the results are most probably due to differences in the familiarity of the programmer with the underlying language... – Pedro Feb 4 '12 at 12:37
@Pedro: I have made your exact argument for years, but, as I mentioned, even with proper restrict usage there tends to still be a small difference in performance. I would expect the situation to change when vector intrinsics are introduced, but that is another story. – Jack Poulson Feb 4 '12 at 15:32
show 8 more comments

Three facts:

  • F77-style n-dimensional arrays in C: No problem using CnD (a shameless plug, admittedly)

  • F90's module system is poorly designed and hostile to build environments. (A module's name doesn't have to match its filename, e.g.)

  • Fortran does not support refactoring well. Pulling some bit of functionality out of a function requires you to touch four places: Actual code, variable declarations, argument declarations, and argument list. C gets by with two places to touch. This compounds the effect of the failure to manage data well (described below): Since small-scale modularity is so painful, just about everybody writes gigantic subroutines.

One personal impression:

  • Fortran does not work well for managing data. Try returning a pointer to a user-opaque data structure in F77 or F90. (transfer(), here we come)
share|improve this answer
Hi Andreas! CnD is interesting, I didn't know about it. Ah, you wrote it. :) (f90 also supports slicing, allocatable for arrays and most importantly -- array syntax for multiplication, addition and so on.) I use CMake with Fortran and it works great with modules. What exactly is "argument list"? I don't think I use these, so only 3 places are needed to modify. In C, you typically need to modify the actual code, parameters and a header file, so it's also 3 places (most definitely in C++). Yes, transfer() isn't super nice, but typically you don't need it in practice. – Ondřej Čertík Dec 13 '11 at 6:24
2  
Refactoring modern fortran is trivial with proper IDEs, like Photran in eclipse. – user389 Feb 5 '12 at 0:37

From my 15 years of thinking about scientific software: If your code runs 25% faster because you write it in Fortran, but it takes you 4 times as long to write it (no STL, difficulty implementing complex data structures, etc), then Fortran only wins if you spend a significant fraction of your day twiddling thumbs and waiting for your computations to finish. Given that for almost all of us the most valuable thing is our own time, the conclusion is this: use the language that allows you to develop, debug and test your code the fastest, within reason ignoring that it may be slower than maybe possible if you wrote it in Fortran.

share|improve this answer

I'm also throwing my two cents in kind of late, but I've only just seen this thread and I feel that, for posterity, there are a few points that desperately need to be made.

Note in the following that I will talk about C and not C++. Why? Well, otherwise it's apples and oranges to compare a full-fledged dynamically typed object-oriented language with something as static as Fortran. Yes, some modern implementations of the latest Fortran standards can do more than just that, but very few people actually use them, and so when we speak of Fortran, we think simple, static, and imperative language. That's where C is too, so I'll replace C with C++ for the following.

First of all, any discussion of Fortran/C having better compilers is moot. Dedicated C/Fortran compilers are a thing of the past. Both gcc/gfortran and icc/ifc are just different front-ends to the same back-end, i.e. your program will be transformed into an abstract description by the front-end and then optimized and assembled by the back-end. If you write, semantically, the same code in Fortran or in C, the compiler will, in both cases, produce the same assembly which will run just as fast.

This now leads to my second point: why do we still see differences? The problem is that most comparisons are made by Fortran programmers trying something in C or vice-versa. Ever notice how most authors or poets prefer to write in their native languages? Would you want to write poetry in a language in which you don't feel completely confident or at home? Of course not... I myself consider C to be my "native" programming language. I did, however, also spend three years working in a group that used only Fortran, in which I have achieved a certain level of fluency. I would, however, never write anything on my own in Fortran since I'm more comfortable with C and, as a consequence, the resulting code will be better, whatever you define that as.

So the main difference is in the programmer, not the language. So there are no differences? Well, not quite. Here are a few examples:

  • SIMD: Whether it's SSE, SSE3 or AltiVec, if you want to use them in Fortran, you better hope and pray that the compiler guesses exactly what you want and does it so. Good luck. In C you generally have intrinsic functions for each architecture, or, more recently, general SIMD vector types in gcc. Most Fortran compilers will only use SIMD instructions to unroll loops, but if you have a kernel which works on short vectors of data in a non-obvious way, the compiler will very probably not see it.

  • Different hardware architectures: The whole CUDA architecture is built around kernels in C. Yes, the Portland Group now has a CUDA-capable fortran compiler too, but it's commercial, and most importantly, it's not from NVIDIA. Same goes for OpenCL, for which the best I could find is a recent project which only supports a few basic calls.

  • Parallel programming: Yes, both MPI and OpenMP work just fine with both C and Fortran. However, if you want real control of your threads, i.e. if you have a fully dynamic shared-memory computation, you'll be out in the cold with Fortran. In C you have the standard pthreads which, while not warm and fuzzy, will still get you through the storm. In general, most computations that rely on access to the operating system, e.g. threads, processes, file system, etc... are better served with C. Oh, and don't try to do your own networking with Fortran.

  • Ease of use: Fortran is closer to Matlab than C is. Once you've gotten over all the different keywords and how to declare variables, the rest of the code looks like Matlab, making it more accessible to users with limited programming experience.

  • Interoperability: When you create a struct in C, the layout of the actual data is straight-forward and deterministic. In Fortran, if you use pointer arrays or structured data, the actual layout of the data is strongly compiler-dependent, not straight-forward, and usually completely undocumented. You can call C from Fortran and vice-versa, but don't start thinking it may be as easy to pass anything more than a static array from one to the other and back.

This is all somewhat geeky, low-level stuff, but this is High-Performance Computing we're talking about, right? If you're not interested in how to best exploit the underlying hardware paradigms, i.e. implementing and/or developing algorithms which are best for shared/distributed memory, threads, SIMD vectorisation, GPUs using SIMT, and so-on, then you're just doing math on a computer.

This has gotten much longer that anything I entended, so here's a summary -- a set of take home messages of sorts:

  • You will write the best code you can in the language which you know best.
  • There is no difference in the quality of code produced by two compilers which use the same back-end -- it is us who write bad code in one language or another.
  • Despite feeling more low-level, Fortran is quite a high-level abstraction and won't let you access certain hardware/OS features directly, e.g. SIMD, threads, networking, etc...
share|improve this answer
1  
Good response. I don't think however your final comment is necessarily true. I'm a C programmer myself, but you get access to low level things in Fortran through good programming practices. The ideal way to utilize things like SIMD ops is to write code which strongly suggests it (blocking loops out, for example) and let the compiler do it for you. For threading, simply use openMP (pthreads is also usable with some extra work). Fortran has all of the things you mention it doesn't, just at a level that matters to its typical user: numerical. – Reid.Atcheson Feb 4 '12 at 17:31
@Reid.Atcheson: Well, if you block-out everything such that the compiler will catch it, then it will work automagically both in C and in Fortran. The problem is, though, how far do you want to trust your compiler? And why do you want to have to trust it in cases when you know exactly what you want done? OpenMP does threading, yes, but block-wise. You can trick it into getting different thread pools to do different things, but that is just mis-using OpenMP. Pthreads for Fortran are just wrappers to the C functions. I agree, though, that Fortran is easier if you're not into the details. – Pedro Feb 4 '12 at 18:10
Sure you aren't going to get full-blown 99% peak efficiency relying on the compiler, but you can easily come quite close. Beyond this you either have to use intrinsics or inline ASM. You have to make concessions somewhere for overall programmer efficiency, that's why programming languages exist in the first place. At the stage that you actually are insane enough to get into the details of intrinsics or ASM (I have been a few times), Fortran isn't a crutch. You'd know how to link in your assembled hand-optimized code anyways. – Reid.Atcheson Feb 4 '12 at 18:19
@Reid.Atcheson: Well, I'd argue that for parallel HPC applications, you may well end up far below 99% peak efficiency... And the gcc vector types make using intrinsics a non-issue :) – Pedro Feb 4 '12 at 19:11
Thanks for mentioning that actually. I don't know how the vector types slipped under my radar, I'm going to start using them though. You will end up far below 99% peak efficiency, I was kind of exaggerating. I'll happily sacrifice runtime for my programming time if I think it'll keep me from pulling my hair out. Still do my best for efficiency. I only resort to a serious optimization attempt if it's absolutely necessary. – Reid.Atcheson Feb 4 '12 at 20:10
show 1 more comment

The problem with C++ is that you have numerous chances to ruin performance, for instance by blindly using STL, exceptions, classes (virtual overhead plus alignment problems), operator overloading (redundant new/deletes) or templates (never-ending compilation and cryptic errors seem benign, but you can waste hours this way).

However, more you gain better access to general libraries and possibly grater visibility of your code (although this strongly depends on the field, and you still have pure C). And you can still compensate the Fortran's lack of flexibility by wrapping its code in a script language like R, Lush, Matlab/Scilab or even Python, Ruby or Lua.

share|improve this answer
1  
It is generally a bad idea to apply low-level techniques in high-level languages. For example, the STL is designed to operate on a very abstract level. One has to be aware what the interface is designed for, use it for this task and then get out of the compilers way. – Martin Dec 8 '11 at 19:51
I think both mbq's and Martin's points are unfair. Yes, there are ways to shoot yourself in the foot if you try to implement a numeric vector for linear algebra purposes using std::list<double>. But that's a silly argument: at least C++ has a linked list class that you can use, while Fortran doesn't. It's like saying "Cars drive at such high speed that you could crash into a wall and get injured; you should use horse-drawn carriages instead." It's just a silly idea to trash a high-level language that also supports low-level stuff (e.g. C++) for having high-level features. – Wolfgang Bangerth Mar 23 '12 at 17:41
@WolfgangBangerth No, now you are hurting Fortran -- it is as "low-level" as bacteria are "less evolved" then humans. If you want a car analogy, it should be more like "you can use both Jeep and Lexus to cross a swampy byway, but using the first one hurts less". – mbq Mar 23 '12 at 19:13
I appreciate your opinion, but I do maintain that Fortran isn't as evolved as C++ is :-) – Wolfgang Bangerth Mar 23 '12 at 21:37

Since I am new here, I was looking through old questions and found this one. Hopefully it's not taboo to answer old ones!

Since no one else has mentioned this, figured I would. Fortran 2003 is almost fully supported by most of the major compilers (intel, ibm, cray, NAG, PCG) even gcc with the (soon-to-be) newest release 4.7. Fortran 2003 (and 2008) is an object oriented language, albeit a bit more verbose than C++. One of things that I think is nice about Fortran is the fact that the standard committee see's scientific computing as it's primary audience (I thank Damian Rouson for pointing this out to me the other day).

I bring this all up not so that C++ programmers become Fortran programmers, but so that Fortran people know that they have more options now besides switching to C++ or emulating object oriented concepts in Fortran 90/95.

One caveat I will add is that there is a cost to being on the bleeding edge of what's implemented in the compilers. If you undertake a major project in Fortran 2003 right now you will stumble across bugs and continually need to update your compiler (especially if you use gcc), though this has gotten significantly better in the past few months!

share|improve this answer

Fortran is optimized for array/matrix computations and is a thorough pain to work with for any type of text parsing. C and C++ may not match up with Fortran in numerical computing (it's close),but I find it much easier to process text and organize data (i.e. custom data structures) with C/C++.

As others have mentioned, don't count out dynamic interpreted languages (Python et al). They may not offer the face-melting speed of Fortan up front, but they allow you to focus more on solving your computational problem than all the details of implementation. Often you can implement a solution in Python, and if the performance is unacceptable, do some profiling, identify the problem areas, and either optimize that code using Cython or re-implement the entire program in a compiled language. Once you have the problem-solving logic fleshed out, the rest is just implementation and, with a good understanding of computing fundamentals, should be straightforward to represent in any variety of programming languages.

share|improve this answer
That's right. For text parsing I also use Python. – Ondřej Čertík Dec 13 '11 at 6:27
You can also implement part of a Python script in a compiled language e.g. C++ and hook it in. E.g. Boost Python, Swig etc. – Faheem Mitha Dec 13 '11 at 8:05

I'm currently working at one of the national labs. Most of the folks around me are mechanical engineers. Chatting with some of the folks in the HPC groups, they're doing mostly Linux and mostly C++. The group I'm currently in does mostly desktop applications and we use Windows and in descending order: C#, FORTRAN, Python, VBA and VB (6, not .NET). Some of the simulation engines we use were written at other national labs in FORTRAN.

share|improve this answer

What Jack P. I think is trying to say is that you should mix and match. A good piece of software is carefully layered. Different layers may map more naturally, or efficiently, to different languages. You should choose the most appropriate language for each layer. You should also understand how languages can interoperate, which may affect what language you choose for what layer.

A better question is what examples of excellently designed software are out there that are worth studying to learn about how to design layered software.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.