Matti Wens
Matti Wens

Reputation: 750

Optimizing multiplication by zero

I have the following line in some Fortran code:

acc = acc + DRSite_t(u, k, s) * Exp(-(max(0.0_dp, t1 - real(s, dp)) / TAT(ds, k)))

where DRSite_t and TAT are both arrays not functions.

Obviously, if the DRSite_t value is zero, the complex calculation to the right of the multiply operator will not need to be evaluated.

Is a modern compiler at all likely to pick up on this and optimize, or should I wrap it in an if block?

Or is this a case where I should just suck it and see? I'm using gfortran if that makes any difference, but it would be interesting to hear if different compilers would handle things differently.

Upvotes: 3

Views: 658

Answers (2)

francescalus
francescalus

Reputation: 32366

As usual when floating point arithmetic happens, things can get interesting. In this case, it is not certain that 0*expr is equivalent to 0.

Consider possibilities for the expression on the right-hand side, under IEEE arithmetic. We could get:

  • a NaN result, for an infinite (either sign) or NaN expression;
  • a result -0, for a negative finite expression when signed zeroes are supported;
  • a result 0, for a positive finite value, or any finite value when signed zeroes are not supported.

For the first two, there could be flag setting, which may further lead to halting.

Also, if expr is a function reference that function may have side effects.

Now, in the case of the question, the programmer may "know" that TAT (if a function) has no side effects and is a (strictly) positive value and that the exponentiation there has a positive finite result. The compiler has to be absolutely certain of that, or know that the programmer doesn't care.

If TAT(ds,k) cannot be proven (to the compiler's satisfaction) positive, under IEEE arithmetic it would be wrong to "optimize".

That is, the compiler would have to check:

  • is DRSite_t(u, k, s) zero; and
  • does the exponential have an exceptional value; and
  • does any function reference have a side effect?

That's a lot of effort and in a general setting is not feasible.

To conclude, if you are sure that 0*expr is indeed equivalent to 0 it is worth looking at skipping the entire assignment statement; but it would be a brave compiler to do that for you. The best chance of having this conditional assignment good is if TAT is an expensive, but well behaved, function.

Upvotes: 3

You mean if first computes DRSite_t(u, k, s), checks whether it is equal to 0 and then potentially skips the other part of the expression?

I am quite sure the compiler does not do that. It would cause a lot of slowdown instead of speedup in too many cases. Branching is really expensive.

I even think that if you do this by hand, it will be slower, unless the 0 comes very often. But the compiler has no reason to assume that the 0 happens very often.

Upvotes: 4

Related Questions