<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Internal procedures are in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954051#M93024</link>
    <description>&lt;P&gt;Internal procedures are semantically distinct from module procedures and BIND(C) procedures may handle the VALUE attribute differently as well.&amp;nbsp;Have you measured the effect of making function ack a module procedure and of giving it the BIND(C) attribute (8 tests in all)?&lt;/P&gt;</description>
    <pubDate>Thu, 20 Mar 2014 01:20:05 GMT</pubDate>
    <dc:creator>JVanB</dc:creator>
    <dc:date>2014-03-20T01:20:05Z</dc:date>
    <item>
      <title>Recursive function and pass by VALUE optimizations</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954050#M93023</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;

&lt;P&gt;I have some questions about the recursive functions performance in the compiler.&lt;/P&gt;

&lt;P&gt;The code is below, the performance table obtains with the compiler 14.&amp;nbsp; First column is normal, second column is pass by value.&lt;/P&gt;

&lt;P&gt;Ifort is slower than gfortran(4.8.2), and is passing by reference creating more copies in the recursive case ?&lt;/P&gt;

&lt;P&gt;I don't know if performance is better with old compiler version.&lt;/P&gt;

&lt;P&gt;Thanks.&lt;/P&gt;

&lt;P&gt;ifort&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.51&amp;nbsp; 1.151&lt;/P&gt;

&lt;P&gt;gfortran&amp;nbsp; 2.027&amp;nbsp; 0.452&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;
program ackermann
         implicit none
   write(*,*) ack(3, 12)
   contains
 recursive function ack(m, n) result(a)
   integer, intent(in) :: m,n
   integer :: a

   if (m == 0) then
     a=n+1
   else if (n == 0) then
     a=ack(m-1,1)
   else
     a=ack(m-1, ack(m, n-1))
   end if
 end function ack
 end program ackermann&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Mar 2014 21:16:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954050#M93023</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-19T21:16:39Z</dc:date>
    </item>
    <item>
      <title>Internal procedures are</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954051#M93024</link>
      <description>&lt;P&gt;Internal procedures are semantically distinct from module procedures and BIND(C) procedures may handle the VALUE attribute differently as well.&amp;nbsp;Have you measured the effect of making function ack a module procedure and of giving it the BIND(C) attribute (8 tests in all)?&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 01:20:05 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954051#M93024</guid>
      <dc:creator>JVanB</dc:creator>
      <dc:date>2014-03-20T01:20:05Z</dc:date>
    </item>
    <item>
      <title> </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954052#M93025</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Putting the function in a module with or without bind(C) doesn't change the results.&lt;/P&gt;

&lt;P&gt;The gap of performance between value and no value&amp;nbsp; , and between ifort and gfortran is still there.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 16:00:29 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954052#M93025</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-20T16:00:29Z</dc:date>
    </item>
    <item>
      <title>I tried this with gfortran 4</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954053#M93026</link>
      <description>&lt;P&gt;I tried this with gfortran 4.8.2 and ifort 14.0.2 was faster by about 10%. But this is hardly representative of a real application. Is this just a question of academic interest?&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 17:36:34 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954053#M93026</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2014-03-20T17:36:34Z</dc:date>
    </item>
    <item>
      <title> </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954054#M93027</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Can you please provide your options ? in which case ifort was faster w/witout value?&amp;nbsp;&lt;/P&gt;

&lt;P&gt;I'm&amp;nbsp; running on a &amp;nbsp;Intel(R) Core(TM) i7-3520M, i compile with -O3 and fast.&lt;/P&gt;

&lt;P&gt;No, by pure curiosity and interest for the language , and as I'm used to see ifort being faster I was surprise. Also I'd like to know why in this case passing by value is faster, so maybe i can use it in my real codes.&lt;/P&gt;

&lt;P&gt;Thanks.&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 18:38:33 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954054#M93027</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-20T18:38:33Z</dc:date>
    </item>
    <item>
      <title>I just used -O2 on a Core i7</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954055#M93028</link>
      <description>&lt;P&gt;I just used -O2 on a Core i7 965 (Nehalem). I didn't try adding VALUE. You didn't show how you changed the code to pass and receive by value - I would not normally expect that to make any noticeable difference. Perhaps something else is going on.&lt;/P&gt;

&lt;P&gt;Were you building 32-bit or 64-bit? If 64-bit, I could understand VALUE being faster due to the arguments being passed in registers rather than on the stack.&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 18:51:22 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954055#M93028</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2014-03-20T18:51:22Z</dc:date>
    </item>
    <item>
      <title> </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954056#M93029</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;I&amp;nbsp; am on a 64 bit. here is how i put by value :&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;
integer, intent(in),value :: m,n&lt;/PRE&gt;

&lt;P&gt;without value , gfortran -O2 gives&amp;nbsp; 3.598s&amp;nbsp; with -O3 2.022s .&lt;/P&gt;

&lt;P&gt;with value , gfortran -O2 gives&amp;nbsp;0.767s&amp;nbsp; with -O3&amp;nbsp;0.458s .&lt;/P&gt;

&lt;P&gt;without value , ifort -O2 gives&amp;nbsp;m3.579s&amp;nbsp; with -O3 3.572s .&lt;/P&gt;

&lt;P&gt;with value , ifort -O2 gives&amp;nbsp;0.964s&amp;nbsp; with -O3 0.972s&lt;/P&gt;

&lt;P&gt;Pat.&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 19:50:33 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954056#M93029</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-20T19:50:33Z</dc:date>
    </item>
    <item>
      <title>With value attribute, the m-1</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954057#M93030</link>
      <description>&lt;P&gt;With value attribute,&amp;nbsp;the m-1 and n-1 in "a=ack(m-1, ack(m, n-1))" need not be written to temporary stack variable in caller (to be passed by reference to callee). It should eliminate two writes and two reads per call (assuming fast call being used, x64 uses fast call by default, x32 depends on options).&lt;/P&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 20:00:36 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954057#M93030</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-20T20:00:36Z</dc:date>
    </item>
    <item>
      <title>Timing a function like this</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954058#M93031</link>
      <description>&lt;P&gt;Timing a function like this example bad practice since it leads one to bad assumptions (generalities)&amp;nbsp;about optimizations in total. If you are really concerned about performance... for this function... then you would make it an iterative process as opposed to a recursive process. Doing so would make it much more efficient (execution wise).&lt;/P&gt;

&lt;P&gt;The following is a C++ example illustrating this (I will let you convert this to Fortran):&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;

// Serial recursive method to calculate Fibonacci series
long SerialFib( long n )
{
&amp;nbsp;if( n&amp;lt;2 )
&amp;nbsp;&amp;nbsp;return n;
&amp;nbsp;else
&amp;nbsp;&amp;nbsp;return SerialFib(n-1)+SerialFib(n-2);
}

// Serial non-recursive method to calculate Fibonacci series
// *** Note, several orders of magnitude faster than all
// *** recursive techniques.
long SerialFib2( long n )
{
&amp;nbsp;if( n&amp;lt;2 )
&amp;nbsp;&amp;nbsp;return n;
&amp;nbsp;long fib0 = 1;&amp;nbsp;// most recent
&amp;nbsp;long fib1 = 1;&amp;nbsp;// 1 prior to most recent
&amp;nbsp;long fib2 = 0;&amp;nbsp;// 2 prior to most recent
&amp;nbsp;long i;
&amp;nbsp;for(i=2; i&amp;lt;n; ++i)
&amp;nbsp;{
&amp;nbsp;&amp;nbsp;fib2 = fib1;
&amp;nbsp;&amp;nbsp;fib1 = fib0;
&amp;nbsp;&amp;nbsp;fib0 = fib1 + fib2;
&amp;nbsp;}
&amp;nbsp;return fib0;
}&lt;/PRE&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 20:08:18 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954058#M93031</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-20T20:08:18Z</dc:date>
    </item>
    <item>
      <title>That's not enough to pass by</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954059#M93032</link>
      <description>&lt;P&gt;That's not enough to pass by value in standard Fortran. ifort has a bug where it DOES cause pass/receive by value, I didn't think gfortran has the same bug. We do it the right way if you say -standard-semantics, which is to pass an anonymous copy by reference. You'd need to add BIND(C) to have VALUE mean pass-by-value. Looking at gfortran's generated code, with VALUE, I do see it putting the argument directly into the registers rather than a temp. Maybe it figures that it can see the whole program so it's safe to do so.&lt;/P&gt;

&lt;P&gt;That said, I do see that adding VALUE does significantly improve the performance if -standard-semantics is not used.&lt;/P&gt;

&lt;P&gt;Anyway, here are the timings I get:&lt;/P&gt;

&lt;P&gt;gfortran with and without VALUE: 5.700 6.055&lt;/P&gt;

&lt;P&gt;ifort with and without VALUE: 1.438 4.714&lt;/P&gt;

&lt;P&gt;How did you do your timings? I added code to the program using SYSTEM_CLOCK like this:&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;
program ackermann
         implicit none
         integer(8) start, end, rate
         write (*,*) "Start"
         call system_clock(start)
   write(*,*) ack(3,12) ! 12)
   call system_clock (end, rate)
   write (*,*) "Time: ", real(end-start)/real(rate)
   contains
 recursive function ack(m, n) result(a)
   integer, intent(in) :: m,n
   integer :: a

   if (m == 0) then
     a=n+1
   else if (n == 0) then
     a=ack(m-1,1)
   else
     a=ack(m-1, ack(m, n-1))
   end if
 end function ack
 end program ackermann&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 20:22:18 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954059#M93032</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2014-03-20T20:22:18Z</dc:date>
    </item>
    <item>
      <title> </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954060#M93033</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Thanks for the explanation . Actually I'm not sure how easy the ackermann function is to serialize. Also i understand changing to a faster algorithm, but that's not the point here.&lt;/P&gt;

&lt;P&gt;I use my time shell function , but here are the result i got with your code :&lt;/P&gt;

&lt;P&gt;gfortran -O3 test.f90&lt;BR /&gt;
	./a.out&lt;BR /&gt;
	&amp;nbsp;Start&lt;BR /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32765&lt;BR /&gt;
	&amp;nbsp;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.02059364&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;
	ifort -O3 test.f90&lt;BR /&gt;
	&amp;nbsp;./a.out&lt;BR /&gt;
	&amp;nbsp;Start&lt;BR /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32765&lt;BR /&gt;
	&amp;nbsp;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.741407&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/P&gt;

&lt;P&gt;With value :&lt;/P&gt;

&lt;P&gt;gfortran -O3 test.f90&lt;BR /&gt;
	&amp;nbsp;./a.out&lt;BR /&gt;
	&amp;nbsp;Start&lt;BR /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32765&lt;BR /&gt;
	&amp;nbsp;Time:&amp;nbsp;&amp;nbsp; 0.458827287&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;
	&amp;nbsp;ifort -O3 test.f90&lt;BR /&gt;
	&amp;nbsp;./a.out&lt;BR /&gt;
	&amp;nbsp;Start&lt;BR /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32765&lt;BR /&gt;
	&amp;nbsp;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.066044&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/P&gt;

&lt;P&gt;&lt;BR /&gt;
	&amp;nbsp;gfortran -v&lt;BR /&gt;
	Using built-in specs.&lt;BR /&gt;
	COLLECT_GCC=gfortran&lt;BR /&gt;
	COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/lto-wrapper&lt;BR /&gt;
	Target: x86_64-unknown-linux-gnu&lt;BR /&gt;
	Configured with: /build/gcc/src/gcc-4.8-20140206/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --disable-cloog-version-check --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --disable-multilib --disable-werror --enable-checking=release&lt;BR /&gt;
	Thread model: posix&lt;BR /&gt;
	gcc version 4.8.2 20140206 (prerelease) (GCC)&lt;/P&gt;

&lt;P&gt;ifort -v&lt;BR /&gt;
	ifort version 14.0.1&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 20:37:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954060#M93033</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-20T20:37:47Z</dc:date>
    </item>
    <item>
      <title>Wrote up a Fortran variation:</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954061#M93034</link>
      <description>&lt;P&gt;Wrote up a Fortran variation:&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;
!&amp;nbsp; Fibonacci.f90 
module Fibs
contains
recursive integer(8) function SerialFib( n )
&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp; integer :: n
&amp;nbsp;&amp;nbsp;&amp;nbsp; if( n .lt. 2) then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SerialFib = n
&amp;nbsp;&amp;nbsp;&amp;nbsp; else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SerialFib = SerialFib(n-1) + SerialFib(n-2)
&amp;nbsp;&amp;nbsp;&amp;nbsp; endif
end function SerialFib

integer(8) function SerialFib2( n )
&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp; integer :: n, i
&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(8) :: fib0, fib1, fib2
&amp;nbsp;&amp;nbsp;&amp;nbsp; if(n .lt. 2) then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SerialFib2 = n
&amp;nbsp;&amp;nbsp;&amp;nbsp; else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib0 = 1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib1 = 1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib2 = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i=2,n-1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib2 = fib1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib1 = fib0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fib0 = fib1 + fib2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; enddo
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SerialFib2 = fib0
&amp;nbsp;&amp;nbsp;&amp;nbsp; endif
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
end function SerialFib2
end module Fibs

program Fibonacci
&amp;nbsp;&amp;nbsp;&amp;nbsp; use omp_lib ! omp_get_wtime()
&amp;nbsp;&amp;nbsp;&amp;nbsp; use Fibs
&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none

&amp;nbsp;&amp;nbsp;&amp;nbsp; real(8) :: t1, t2, t3
&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(8) :: fib, fib2
&amp;nbsp;&amp;nbsp;&amp;nbsp; integer :: in
&amp;nbsp;&amp;nbsp;&amp;nbsp; in = 45
&amp;nbsp;&amp;nbsp;&amp;nbsp; t1 = omp_get_wtime()
&amp;nbsp;&amp;nbsp;&amp;nbsp; fib = SerialFib(in)
&amp;nbsp;&amp;nbsp;&amp;nbsp; t1 = omp_get_wtime() - t1
&amp;nbsp;&amp;nbsp;&amp;nbsp; print *, in, fib, t1

&amp;nbsp;&amp;nbsp;&amp;nbsp; t2 = omp_get_wtime()
&amp;nbsp;&amp;nbsp;&amp;nbsp; fib2 = SerialFib2(in)
&amp;nbsp;&amp;nbsp;&amp;nbsp; t2 = omp_get_wtime() - t2
&amp;nbsp;&amp;nbsp;&amp;nbsp; print *, in, fib2, t2

&amp;nbsp;&amp;nbsp;&amp;nbsp; in = in * 2
&amp;nbsp;&amp;nbsp;&amp;nbsp; t3 = omp_get_wtime()
&amp;nbsp;&amp;nbsp;&amp;nbsp; fib2 = SerialFib2(in)
&amp;nbsp;&amp;nbsp;&amp;nbsp; t3 = omp_get_wtime() - t3
&amp;nbsp;&amp;nbsp;&amp;nbsp; print *, in, fib2, t3

&amp;nbsp;&amp;nbsp;&amp;nbsp; end program Fibonacci

&lt;/PRE&gt;

&lt;PRE class="brush:plain;"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 45&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1134903170&amp;nbsp;&amp;nbsp; 9.69680809543934
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 45&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1134903170&amp;nbsp; 0.000000000000000E+000
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 90&amp;nbsp;&amp;nbsp; 2880067194370816120&amp;nbsp; 3.001186996698380E-007
Press any key to continue . . .&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Running recursive with input of 45 took 9.7 seconds, iterative was too short to measure.&lt;BR /&gt;
	Input of 90 would take too long to run recursively, and would likely exhaust the stack, the iterative method, barely measurable using omp_get_wtime().&lt;/P&gt;

&lt;P&gt;This example, is computationally equivalent to the example provided by Ackermann&lt;/P&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;</description>
      <pubDate>Thu, 20 Mar 2014 21:46:53 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954061#M93034</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-20T21:46:53Z</dc:date>
    </item>
    <item>
      <title>Quote:pat97269 wrote:</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954062#M93035</link>
      <description>&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;pat97269 wrote:&lt;BR /&gt; Actually I'm not sure how easy the ackermann function is to serialize. &lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;

&lt;P&gt;I remember my sophomore CS instructor giving us an assignment to write a serial version of the Ackermann function. Drove me crazy. I never forgave him when he later told us that it was not possible. See &lt;A href="http://en.wikipedia.org/wiki/Ackermann_function" target="_blank"&gt;http://en.wikipedia.org/wiki/Ackermann_function&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 21 Mar 2014 01:15:13 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954062#M93035</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2014-03-21T01:15:13Z</dc:date>
    </item>
    <item>
      <title> </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954063#M93036</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;I clearly understand some algorithms are faster than other. But that doesn't remove the point that in that case,&amp;nbsp; on my processor, the performance are surprising, and as i understand passing by value in this case allow speedup the computation a little bit. It doesn't explain the difference in performance with steve result.&lt;/P&gt;

&lt;P&gt;I will try to run that on other processor and see.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Thanks&lt;/P&gt;</description>
      <pubDate>Fri, 21 Mar 2014 02:48:51 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954063#M93036</guid>
      <dc:creator>pat97269</dc:creator>
      <dc:date>2014-03-21T02:48:51Z</dc:date>
    </item>
    <item>
      <title>For what it is worth, here is</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954064#M93037</link>
      <description>&lt;P&gt;For what it is worth, here is an assembler version of the ack(m,n) function, callable from C. Other than depending on the recursion relations to compute the function, it contains 16 instructions, of which only three access memory and consume stack. On a C2D E8400 3 GHz CPU OpenSuse system, the program computed ack(3,12) in 1.4 seconds.&lt;/P&gt;

&lt;P&gt;[bash]&lt;/P&gt;

&lt;P&gt;# int ack(int m,int n), 64-bit GCC calling convention&lt;/P&gt;

&lt;P&gt;#&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;.text&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;.globl ack&lt;/P&gt;

&lt;P&gt;ack: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;# &amp;nbsp; m in edi, n in esi&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;test %edi,%edi &amp;nbsp; &amp;nbsp; # m==0?&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jz l1&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;test %esi,%esi &amp;nbsp; &amp;nbsp; # n==0?&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jz l2&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %esi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # n--&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;push %rdi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# save m; no need to save n&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;call ack &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # ack(m,n-1)&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;pop %rdi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # restore m&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;mov %eax, %esi &amp;nbsp; &amp;nbsp; # ack(m,n-1)&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %edi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # m-1&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jmp ack &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# ack(m-1,ack(m,n-1))&lt;/P&gt;

&lt;P&gt;l1:&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;leal 1(%esi),%eax &amp;nbsp;# m=0: return n+1&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;&amp;nbsp; &amp;nbsp;ret&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;l2:&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %edi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # n=0; return ack(m-1,1)&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;inc %esi&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jmp ack&lt;/P&gt;

&lt;P&gt;#&lt;/P&gt;

&lt;P&gt;#END&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;[/bash]Compiler options are irrelevant since the driver (see below) consumes very little time (parsing the command arguments, calling the function, and printing the result).&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;[cpp]#include &amp;lt;stdio.h&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/P&gt;

&lt;P&gt;extern int ack(int m,int n);&lt;/P&gt;

&lt;P&gt;main(int argc,char *argv[]){&lt;/P&gt;

&lt;P&gt;int m,n;&lt;/P&gt;

&lt;P&gt;if(argc-3){&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;fprintf(stderr,"Usage: ackd &amp;lt;m&amp;gt; &amp;lt;n&amp;gt;\n");&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;exit(1);&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;

&lt;P&gt;m=atoi(argv[1]); n=atoi(argv[2]);&lt;/P&gt;

&lt;P&gt;printf("%2d %2d %d\\n",m,n,ack(m,n));&lt;/P&gt;

&lt;P&gt;}&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;[/cpp]&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 22 Mar 2014 00:19:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954064#M93037</guid>
      <dc:creator>mecej4</dc:creator>
      <dc:date>2014-03-22T00:19:00Z</dc:date>
    </item>
    <item>
      <title>mecej4,</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954065#M93038</link>
      <description>&lt;P&gt;mecej4,&lt;/P&gt;

&lt;P&gt;Great post. In looking at the assembler code, I think one can convert it into a arguable iterative process. Here is my thought (not tested in code)&lt;/P&gt;

&lt;P&gt;On entry to ack: you&amp;nbsp;copy %esp to&amp;nbsp;%ecx (or rcx when coding x64)&lt;BR /&gt;
	After that you add tag ack_loop:&lt;BR /&gt;
	Replace the "call ack" with "jmp ack_loop"&lt;BR /&gt;
	Move the code following the former "call ack" to in front of the "ret"&lt;BR /&gt;
	Add following the above moved code (before the ret) "pop %rdi; cmp %ecx,%esp;&amp;nbsp;jnz ack_loop"&lt;/P&gt;

&lt;P&gt;Effectively what you are doing is replacing the call stack with a data stack. The function code is iterative, however it uses a stack-like data structure (that resides on&amp;nbsp;the stack for storage).&lt;/P&gt;

&lt;P&gt;So does this then exemplifie an iterative process that implements the Ackerman's function?&lt;/P&gt;

&lt;P&gt;--- Edit ---&lt;/P&gt;

&lt;P&gt;Untested code:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;
# int ack(int m,int n), 64-bit GCC calling convention
#
&amp;nbsp;&amp;nbsp; .text
&amp;nbsp;&amp;nbsp; .globl ack
ack:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp; m in edi, n in esi
&amp;nbsp;&amp;nbsp; mov %esp,%ecx
ack_loop:
&amp;nbsp;&amp;nbsp; test %edi,%edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # m==0?
&amp;nbsp;&amp;nbsp; jz l1
&amp;nbsp;&amp;nbsp; test %esi,%esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n==0?
&amp;nbsp;&amp;nbsp; jz l2
&amp;nbsp;&amp;nbsp; dec %esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n--
&amp;nbsp;&amp;nbsp; push %rdi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # save m; no need to save n
&amp;nbsp;&amp;nbsp; jmp ack_loop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m,n-1)
l1:
&amp;nbsp;&amp;nbsp; leal 1(%esi),%eax&amp;nbsp; # m=0: return n+1
&amp;nbsp;&amp;nbsp; pop %rdi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # restore m
&amp;nbsp;&amp;nbsp; mov %eax, %esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m,n-1)
&amp;nbsp;&amp;nbsp; dec %edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # m-1
&amp;nbsp;&amp;nbsp; cmp %ecx,%esp
&amp;nbsp;&amp;nbsp; jne ack_loop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m-1,ack(m,n-1))
&amp;nbsp;&amp;nbsp; ret
l2:
&amp;nbsp;&amp;nbsp; dec %edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n=0; return ack(m-1,1)
&amp;nbsp;&amp;nbsp; inc %esi
&amp;nbsp;&amp;nbsp; jmp ack_loop
#
#END

&lt;/PRE&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;

&lt;P&gt;&lt;BR /&gt;
	&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 23 Mar 2014 15:02:38 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954065#M93038</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-23T15:02:38Z</dc:date>
    </item>
    <item>
      <title>In looking at the code, you</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954066#M93039</link>
      <description>&lt;P&gt;In looking at the code, you could optimize to:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;
# int ack(int m,int n), 64-bit GCC calling convention
#
&amp;nbsp;&amp;nbsp; .text
&amp;nbsp;&amp;nbsp; .globl ack
ack:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp; m in edi, n in esi
&amp;nbsp;&amp;nbsp; mov %esp,%ecx
ack_loop:
&amp;nbsp;&amp;nbsp; test %edi,%edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # m==0?
&amp;nbsp;&amp;nbsp; jz l1
&amp;nbsp;&amp;nbsp; test %esi,%esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n==0?
&amp;nbsp;&amp;nbsp; jz l2
&amp;nbsp;&amp;nbsp; dec %esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n--
&amp;nbsp;&amp;nbsp; push %rdi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # save m; no need to save n
&amp;nbsp;&amp;nbsp; jmp ack_loop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m,n-1)
l1:
&amp;nbsp;&amp;nbsp; inc %esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # m=0: return n+1
&amp;nbsp;&amp;nbsp; pop %rdi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # restore m
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m,n-1)
&amp;nbsp;&amp;nbsp; dec %edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # m-1
&amp;nbsp;&amp;nbsp; cmp %ecx,%esp
&amp;nbsp;&amp;nbsp; jne ack_loop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ack(m-1,ack(m,n-1))
&amp;nbsp;&amp;nbsp; ret
l2:
&amp;nbsp;&amp;nbsp; dec %edi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # n=0; return ack(m-1,1)
&amp;nbsp;&amp;nbsp; inc %esi
&amp;nbsp;&amp;nbsp; jmp ack_loop
#
#END

&lt;/PRE&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;</description>
      <pubDate>Sun, 23 Mar 2014 15:07:45 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954066#M93039</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-23T15:07:45Z</dc:date>
    </item>
    <item>
      <title>Jim,</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954067#M93040</link>
      <description>&lt;P&gt;Jim,&lt;/P&gt;

&lt;P&gt;Thanks for your comments. Indeed, as you suggest a register such as RCX can be used to save the value of RSP at function entry, and the RET instruction executed only if RSP and RCX match just before the RET instruction.&lt;/P&gt;

&lt;P&gt;Alternatively, the recursion depth can be held in a register (such as ECX/RCX, again) and the only remaining RET instruction can be preceded by a LOOP instruction. For users' convenience, I include this version below. There is no need for any CALL instruction, but the program still assumes the availability of a stack of sufficient size.&lt;/P&gt;

&lt;P&gt;[bash]&lt;/P&gt;

&lt;P&gt;# int ack(int m,int n), 64-bit GCC calling convention&lt;/P&gt;

&lt;P&gt;#&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;.text&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;.globl ack&lt;/P&gt;

&lt;P&gt;ack: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# &amp;nbsp; m in edi, n in esi&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;&amp;nbsp; &amp;nbsp;movl $1,%ecx &amp;nbsp; &amp;nbsp; &amp;nbsp; # recursion depth + 1&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;ack0:&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;&amp;nbsp; &amp;nbsp;test %edi,%edi &amp;nbsp; &amp;nbsp; # m==0?&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jz l1&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;test %esi,%esi &amp;nbsp; &amp;nbsp; # n==0?&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jz l2&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %esi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # n--&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;push %rdi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# save m; no need to save n&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;inc %ecx &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # recursion depth&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jmp ack0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # ack(m,n-1)&lt;/P&gt;

&lt;P&gt;res:&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;pop %rdi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # restore m&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;mov %eax, %esi &amp;nbsp; &amp;nbsp; # ack(m,n-1)&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %edi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # m-1&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jmp ack0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # ack(m-1,ack(m,n-1))&lt;/P&gt;

&lt;P&gt;l1:&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;leal 1(%esi),%eax &amp;nbsp;# m=0: return n+1&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;loop res &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # if recursion depth is not zero&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;ret&lt;/P&gt;

&lt;P&gt;l2:&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;dec %edi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # n=0; return ack(m-1,1)&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;inc %esi&lt;/P&gt;

&lt;P&gt;&amp;nbsp; &amp;nbsp;jmp ack0&lt;/P&gt;

&lt;P&gt;#&lt;/P&gt;

&lt;P&gt;#END&lt;/P&gt;

&lt;P&gt;[/bash]&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 23 Mar 2014 19:08:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954067#M93040</guid>
      <dc:creator>mecej4</dc:creator>
      <dc:date>2014-03-23T19:08:00Z</dc:date>
    </item>
    <item>
      <title>If a stack is used, it's</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954068#M93041</link>
      <description>&lt;P&gt;If a stack is used, it's still recursive even without an explicit call.&lt;/P&gt;</description>
      <pubDate>Sun, 23 Mar 2014 22:05:40 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954068#M93041</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2014-03-23T22:05:40Z</dc:date>
    </item>
    <item>
      <title>&gt;&gt;If a stack is used, it's</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954069#M93042</link>
      <description>&lt;P&gt;&amp;gt;&amp;gt;If a stack is used, it's still recursive even without an explicit call.&lt;/P&gt;

&lt;P&gt;That is why I called it arguably.&lt;/P&gt;

&lt;P&gt;I will say that in an abstract sense, the formal description of the Ackermann function is recursive, however, I would also argue that the above code is iterative. IMHO&lt;/P&gt;

&lt;P&gt;Jim Dempsey&lt;/P&gt;</description>
      <pubDate>Mon, 24 Mar 2014 17:23:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Recursive-function-and-pass-by-VALUE-optimizations/m-p/954069#M93042</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2014-03-24T17:23:39Z</dc:date>
    </item>
  </channel>
</rss>

