If or function pointers in fortran

Since this is so common with Fortran, I write massive parallel scientific code. At the beginning of my code, I read my config file that tells me what type of solver I want to use. Now this means that in a subroutine (during main run) I have

if(solver.eq.1)then
  call solver1()
elseif(solver.eq.2)then
  call solver2()
else
  call solver3()
endif

      

Edit to avoid some confusion: This is if inside a time integration loop, and I have one inside 3 nested loops.

Now my question is, it wouldn't be better to use pointers to functions, since the variable solver

will not change at runtime, except for the initialization routine.

Obviously, the function pointers are F2003. This shouldn't be a problem if I'm using gfortran 4.6. But I mostly use BlueGene P, there is an f2003 compiler, so I suppose it will work too, although I couldn't find any conclusive evidence on the internet.

+3


source to share


4 answers


Don't know anything about Fortran, this is my answer. The main problem with branching is that the processor is potentially unable to speculatively execute code through them. To mitigate this problem, branch prediction has been proposed (which is very difficult on modern CPUs).

Indirect calls using a function pointer can be a problem for the CPU prediction block. If he cannot predict where the call will go, this will stop the pipeline.

I'm sure the processor will correctly predict that your branch will always be accepted or not accepted, because this is a trivial prediction case.



Perhaps the processor can speculate through an indirect call, maybe it cannot. That's why you need to check which is best.

If this is not possible, you will surely notice in your test.

Also, perhaps you can pull the if test out of your inner loop so it doesn't get called often. This will make the actual work of the industry irrelevant.

+3


source


If you plan to use function pointers once, on initialization, and execute code on BlueGene, isn't your problem related to efficiency? Generally, any initialization that works is ok, if it takes 1sec instead of 1ms it will probably have a 0 impact on the overall execution time.

Code initialization routines for clarity, ease of modification, things like that.



EDIT

My guess is that using function pointers rather than current code will not affect execution speed. But this is just a (possibly educated) guess, and I will be very interested in any data you collect on this matter.

+2


source


If you are deciding procedures, doing non-trivial execution times, then the trivial IF statements are likely to be irrelevant. If sovler routines have a comparable runtine for the IF statement, then the total execution time is very short, so why is your concern? It looks like the optimization is unlikely to pay off.

The first rule of runtime optimization is your code profile, which shows which chunks are consuming the runtime. Otherwise, you will probably be optimizing the parts that are not important, which will do nothing.

For what its worth, someone recently had a very similar problem: Fortran subroutine pointers for array size mismatch

+1


source


After a quick search, I couldn't find an answer to this question, so I ran a little test myself (see this link for Makefile and dependencies). The test consists of:

  • Draw a random number to choose method a , b, or c , which all perform simple addition to their single integer argument
  • Call the selected method 100 million times using either the procedure pointer or if-statements
  • Repeat the above 5 times

Result from gfortran 4.8.5

to CPU E5-2630 v3 @ 2.40GHz

:

Time per call (proc. pointer):       1.89 ns
Time per call (if statement):        1.89 ns

      

In other words, the performance difference is small!

+1


source







All Articles