All references to a RESULT keyword are recursive calls?

All references to a RESULT keyword are recursive calls?

The Intel(R) Fortran Compiler XE 13.0 User and Reference Guides states the following about the RESULT keyword:

However, if you use the RESULT keyword in a FUNCTION statement, you can specify a local variable name for the function result. In this case, all references to the function name are recursive calls, and the function name must not appear in specification statements.

My impression is that RECURSIVE routines are slower than non-RECURSIVE routines due to how variables may be allocated (the reason this was not allowed in F77). If my impression is correct, does that imply that whenever the RESULT keyword is used, there is an performance penalty? I use the RESULT keyword all the time as an alias for the function name, so that I can have descriptive function names (which tend to be relatively long) without having to use that name in the function body. Is this then a bad idea if performance is important?

publicaciones de 8 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

Keywords cannot be referenced -- where such a reference may appear to exist, the keyword will be interpreted as a variable, possibly local and implicitly typed.

I think that you misinterpret the documentation and that your statement about recursion causing slower running is an over-generalization. To address the first point only, consider this example:

The first version, without the RESULT clause:

program xrec

  implicit none

  integer :: n,fac
    n=5

    fac=factorial(n)

    write(*,*)n,fac

    stop
contains

   function factorial(n)

   implicit none

   integer :: n, factorial

   factorial=1

   if(n.le.1)return

   do while(n.gt.1)

      factorial=factorial*n

      write(*,*)n,factorial

      n=n-1

   end do

   return

   end function factorial

end program xrec


In the internal function the function name is used in almost the same ways as a local variable. No recursion occurs, as the lines of output will show.

Next, the same program, slightly modified to use a RESULT clause:


program xrec1

  implicit none

  integer :: n,fac
    n=5

    fac=factorial(n)

    write(*,*)n,fac

    stop
contains

   function factorial(n) result (fact)

   implicit none

   integer :: n, fact

   fact=1

   if(n.le.1)return

   do while(n.gt.1)

      fact=fact*n

      write(*,*)n,fact

      n=n-1

   end do

   return

   end function factorial

end program xrec1


Again, note that no recursion occurs.

mecej4:
The way you use fact as en alias for the function name (and output variable) factorial is exactly how I use it. I think maybe you misinterpreted my question though, or maybe I wasn't so clear to what in the quote I was refering to. The part that I wonder about is this:
[...] all references to the function name are recursive calls, [...]
As I interpret this the compiler creates the same code *as if* the RECURSIVE attrubute were also present. In your examples there aren't any actual recursive calls (only iterations), and, hence, there is no need for the compiler to 'take special care' of how the local variables are stored etc. In the following code there is actual recursion going on:


RECURSIVE FUNCTION factorial(n) RESULT(fact)

INTEGER, INTETNT(IN) :: n

INTEGER :: fact

IF (n .GT. 1) THEN

    fact = n*factorial(n-1)

ELSE

    fact = 1

END FUNCTION factorial

Don't shoot me if the code is flawed, it's just for illustrating actual recursion.
The point is: is the compiler creating machine code as if the function was actually recursive?
And perhaps a follow-up: Even if the RECURSIVE attribute was present in a procedure that do not make any calls to other procedures (and hence cannot be recursive), will the compiler create code as if it actually were recursive?

is the compiler creating machine code as if the function was actually recursive?

I'd expect it to, unless the optimizer is invoked and is smart enough to replace the simpler recursive code with a non-recursive version with the same functionality. Here is the assembler output from your function:
PUBLIC _FACTORIAL
_FACTORIAL PROC NEAR

...

call _FACTORIAL
...

_FACTORIAL ENDP

Even if the RECURSIVE attribute was present in a procedure that do not make any calls to other procedures (and hence cannot be recursive), will the compiler create code as if it actually were recursive?

That would be up to the optimizer to decide. The Fortran standard does not specify such implementation details. The standard does specify in 12.6.5.2.1, w.r.t. the opposite question:

The RECURSIVE prefix-spec shall appear if any procedure defined by the subprogram directly or indirectly invokes itself or any other procedure defined by the subprogram.

The primary code effect of RECURSIVE is to allocate any local variables and data structures on the stack rather than statically. This is required if the procedure can be reentered while it is still active, whether due to an actual recursive call or a call from a thread context. (If OpenMP is enabled, stack storage is used by default.)

This is not really any slower than static storage, but programs that mistakenly assume static storage may give wrong answers.

Steve - Intel Developer Support

Oops, the example in my last code probably mislead this discussion off track from the original question. I'll repose it:
Given a (non-recursive) function using a RESULT keyword, but without the RECURSIVE attribute. Will the machine code for this function differ from that of the same function programmed without using a RESULT keyword?

No. Using RESULT allows you to reference the function and its return value separately. Otherwise, no difference.

Steve - Intel Developer Support

引文:

Espen M. 写道:

Given a (non-recursive) function using a RESULT keyword, but without the RECURSIVE attribute. Will the machine code for this function differ from that of the same function programmed without using a RESULT keyword?


The short answer is "No". In fact, if you compile the two versions of the non-recursive function FACTORIAL above with the /Od /Fa options, you will find the assembler outputs to be identical.

If you compile with debugging enabled, however, the symbol tables may differ slightly.

Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya