Knowing variable value during compiling .vs. read in the variable value at run time, performance difference?

Dear all,

A very lazy and naïve question. Simple example,
case one,
if I set

a = 0.5

in the code and then compile and run.

Or, case two,
if I read in the value of a as 0.5

read (5,*) a

Are there performance difference between the two cases?

I mean if I set a=0.5 in the code instead of read in it, will the compiler optimize for a = 0.5? Or it does not matter?

Thanks much in advance!

[Clarification]
As @nicholaswogan asked, no the question have nothing to do with I/O in anyway. Sorry for the confusion.
I am just asking,
if I set a=0.5, will compiler optimize it for a=0.5 during compiling?
On the other hand, if a is read in as 0.5, then the value of a is only know at run time, so it seems there is no way a = 0.5 is optimized in anyway.

I am actually asking,
we usually read in the value of variable from like txt file, instead of setting them in the code. Because the former does not require recompile the code again and again, while the latter will require recompile the code again and again.
But does latter have some performance advantage because the value of values are know at compiling time?

In somewhat trivial case

  real :: a = 0.5, y
  y = 4.25**a
  print *, y

gfortran -O2 -S produces assembler code without any function call (apart from *write*), apparently providing compiler-calculated value.
I was unable, however, to avoid calling powf function in any scenario where there was a variable instead of constant 4.25 as the base of exponentiation. I thought it might be optimized to use sqrt instead of powf.

1 Like

If a is truly a constant, define it with the parameter value and there is a good chance the compiler will produce a constant; but I did not try it.

The original I/O question is so general only a general answer can be given without writing a book as a reply. I/O is slower, but is often needed when large amounts of data, or values that change between runs are required. Fortran is a compiled language; it is rare to want to have to recompile every time you change a value.

1 Like

Clarification. Which of the two question are you asking

  1. What is the speed of I/O (i.e. the read function)? How slow is compared to filling the memory in a with 0.5 compared to a = 0.5?

  2. Suppose I fill the memory in a with 0.5 via either a = 0.5 or read(5,*) a. Will subsequent calculations with a be faster with one of these methods?

My thoughts on (2): I really doubt the compiler will specialize for a = 0.5. I think subsequent calculations will have identical speed.

2 Likes

Thank you all @msz59 @urbanjost @nicholaswogan !
As @nicholaswogan pointed out, I added clarification.
Sorry for the confusion. I am actually asking if the value of variable, say a=0.5, is known at compiling time, will compiler optimize for a=0.5? If so, it seems setting values in the code can be better than read in them from a file.
But I guess as @nicholaswogan pointed, things like a=0.5 known at compiling time or run time should not matter. Just very lazy to check so just ask here :wink:

If the topic is for Number 2 above, is it also related a bit to optimizations like constant propagation?

Btw, I’ve tried a code like below using https://godbolt.org/

real function square(x)
    real, intent(in) :: x
    real, parameter :: a = 2.0
    square = x ** a
end

then for a = 2.0 it gives (with gfortran-11.2 -O2)

        movss   xmm0, DWORD PTR [rdi]
        mulss   xmm0, xmm0

while a = 3.0 or 0.5 gives

        movss   xmm1, DWORD PTR .LC0[rip]
        movss   xmm0, DWORD PTR [rdi]
        jmp     powf

so not sqrt() for a = 0.5 as mentioned by msz59…
And for integer like integer, parameter :: a = 128, it gives

        movss   xmm0, DWORD PTR [rdi]
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0
        mulss   xmm0, xmm0

(It is interesting to set a to 65535 etc)

1 Like