C++ Optimization – Important Keywords to Speed Up Code

cfortran

I'm porting to C++ and adding a lot of functionality to a numerical application written in Fortran 77. While I hate F77, I have to admit that the thing goes very fast. Now, I'm implementing practically the same structure and algorithm, but nevertheless the difference in the execution time is noticeable. Not big, but it's there. And I'm wondering, could it be that I need to pass extra information to the compiler? The only related information that I've been able to find is a recommendation to use the restrict key word which is supported by g++, but that's all. Hence, my question: Are there anymore keywords important to speedup code in C++ in numerical applications? or maybe compiler directives?

Thanks!

Best Answer

I do not believe that you should focus your optimizations looking for magic keywords, but here goes some tips:

  1. "inline" might do wonders in numerical apps if you have many short numerical functions

  2. Be careful when copying values all around when you could use a reference. This sounds basic but if you have many classes that are copy/assignment compatible your code could be hiding some copies. Make sure your constructors are defined with the "explicit" keyword, that way your compiler will show you where implicit copies are done.

  3. Give C++11 a try. There are some interesting optimizations. There are more things that are solved statically. Also one very interesting thing for your case is the rvalue reference optimization. It is a very important optimization on the return value of functions. You will notice that a lot if you overload operators, which you will do if you operate different units and try to structure your old code.

  4. There are lots of things that can be done with STL and really interesting template metaprograming, but that is a whole different level to what most people is used to.

  5. Do not rely too much on your compiler optimizations. C++ syntax is well known to make life easier for low-level programmers and a nightmare for compiler designers. That is one of the reasons for which good static analyzers took so long to appear. I know that Scott Mayers made that comment and how C++11 improvements will help to get better tools, but cannot quote where he did.

  6. On the line with compilers... do not expect to get SIMD and overall paralel optimizations. Compilers are really bad at it and unless you get your hands dirty with some library for it, your code will target only one core, one thread of your machine.

  7. It might sound silly but the keyword "const" is really important. If you make clear that some value does not change, the compiler will apply a whole extra set of optimizations. Detecting if a variable could be considered const takes some extra parsing that most compilers do not perform not even with optimizations maxed out. Related with this for example, if your loops do not seem to have a clear/constant end, the compiler will not unroll them (or maybe not as good as it could)

However I wonder why you are migrating from Fortran77 to C++. Fortran sure is an old language, but it is the king for mathematics no matter how ugly it looks, the best way to deal with old code is building a good layer and operate it from outside with the new infrastructure and language you want. It is easier said than done, because sure you will have still to fix some Fortran code in order to make it easier to operate from outside.

If you decide to go on with C++ at least you will get much nicer libraries for multithreading (and that is one of the biggest improvements of C++11) where Fortran lags behind. Try to avoid CUDA if not absolutely necessary, it is really good and mature but focused on NVIDIA. I would keep an eye on OpenCL

Be aware that there is one huge difference for Math. In C++ (like most languages), the values of a matrix are stored as a set of rows while Fotran stores them as a set of columns. This makes a huge difference on the best memory usage of your algorithms. Hence if your algorithms are optimized for Fortran, their loops will target columns instead of rows. (look here) That is how seriously Fortran optimized for Mathematics goes.

One final concern. You want to use C++ and not Fotran77. Because you can get a better abstraction and design? Well, that is a good reason, but please, be wary of the market obsession with object oriented programming. It is a good thing, but not a silver bullet. A GUI for example should always be object oriented, but if you do lots of math and move huge amounts of memory, some aspect oriented style would be nice. Even better for your domain problem, have a look at data oriented design as an alternative to object oriented design (and see one case where OOP fails)

Related Topic