From: yaqi on
Hi All,

I knew following piece of code will not be compiled, at least with
Compaq Visual Fortran. My intention of this code is to let the
compiler automatically transform or expand the loop inside the
function (I do not care the code size) if the caller has a SMALL
CONSTANT integer 'd' in its argument list when the compiler is doing
optimization. Because the function is really crucial for the
performance, I want to save computing time as much as I can. So do not
ask me why I want to do this. Actually I guess this idea is similar as
the template in C++.

Are there any ways to implement this idea easily with Fortran?

Thanks!

--------------------------------------------------------------------------
program main

integer :: e, c
e = ad(c, 10)

stop
end program main

integer function ad(c,d)
implicit none
integer :: c
integer, parameter :: d
integer :: i
do i=1,d
c = c + i
end do
ad = c
return
end function
From: Richard Maine on
yaqi <yaqiwang(a)gmail.com> wrote:

> I want to save computing time as much as I can.
....

> do i=1,d
> c = c + i
> end do

The "obvious" way to save a lot of computing time here is to replace the
loop with

c = c + d*i

While that might seem so obvious as to be not worth saying, I have seen
people overlook more obvious things. One of the first rules of
optimization is to look for algorithm improvements instead of cure
optimization tricks. Multiplication would seem like a substantial
algorithm improvement here.

Other than that, no, there is no concept of a "constant" dummy argument.
A dummy argument is a variable by definition.

I note as an aside that having a function that changes the value of its
argument might possibly inhibit some optimizations. (And it is often
considered a bad idea for other reasons as well).

You can, of course, do all kinds of things outside of the language per
se, using macro preprocessors to generate multiple versions of the
function and calling the appropriate one if the argument value is known
at macro-processing time. There is nothing really Fortran-specific about
that.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: highegg on
On Jan 31, 7:06 am, nos...(a)see.signature (Richard Maine) wrote:
> yaqi <yaqiw...(a)gmail.com> wrote:
> > I want to save computing time as much as I can.
>
> ...
>
> > do i=1,d
> > c = c + i
> > end do
>
> The "obvious" way to save a lot of computing time here is to replace the
> loop with
>
> c = c + d*i
>

certainly not. c = c + d*(d+1)/2, more likely :)

> <rest snipped>
From: James Van Buskirk on
"yaqi" <yaqiwang(a)gmail.com> wrote in message
news:7ac8cf62-97a7-49f9-8487-4eb8eaa1533e(a)m34g2000hsf.googlegroups.com...

> I knew following piece of code will not be compiled, at least with
> Compaq Visual Fortran. My intention of this code is to let the
> compiler automatically transform or expand the loop inside the
> function (I do not care the code size) if the caller has a SMALL
> CONSTANT integer 'd' in its argument list when the compiler is doing
> optimization. Because the function is really crucial for the
> performance, I want to save computing time as much as I can. So do not
> ask me why I want to do this. Actually I guess this idea is similar as
> the template in C++.

> Are there any ways to implement this idea easily with Fortran?

You can do something like a C++ template in Fortran, but just like
the C++ template you will need to compile every time you want a new
loop length. I have an example that has a Fortran program invoking
the compiler to create a dynamic link library and then the program
calls LoadLibraryA to link to the code just conpiled. This may be
more like what you want:

http://groups.google.com/group/comp.lang.fortran/msg/b5065aaaad9eb748

Of course it's done in gfortran and C binding, but it would be easier
to have done it with CVF and dfwin.mod. A problem with this approach
is that if you want to redistribute the code you have to include
instructions on installing the compiler as well. You might be better
off in that event to use a freeware compiler as your run-time dll-
generator, or as a more lightweight alternative, a freeware
assembler. For this purpose, FASM would be best suited because there
is even a dll form of it available which would obviate the need for
CreateProcessA and maybe WaitForSingleObject.

There is probably even a Win32 API that permits you to allocate a
block of memory and get an executable address for it so that you
can just poke your code into memory directly and call it via a
Cray pointer.

Although all the above is fun, I might point out that loop unrolling
has limitations. In particular, if the loop is unrolled to such an
extent that it's larger than instruction cache, your code is going
to spend all of its time fetching the instructions from L2 cache or
beyond and very little time actually executing your instructions.
I have a problem like that where it's easy (relatively) to write out
the code but it's way too big for cache and compilers are not as well
equipped to carry out loop systhesis as they are to carry out loop
unrolling, so I would have to rewrite so as to insert the looping by
hand.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Richard Maine on
highegg <highegg(a)gmail.com> wrote:

> On Jan 31, 7:06 am, nos...(a)see.signature (Richard Maine) wrote:
> > yaqi <yaqiw...(a)gmail.com> wrote:
> > > I want to save computing time as much as I can.
> >
> > ...
> >
> > > do i=1,d
> > > c = c + i
> > > end do
> >
> > The "obvious" way to save a lot of computing time here is to replace the
> > loop with
> >
> > c = c + d*i
> >
> certainly not. c = c + d*(d+1)/2, more likely :)

Um. Er. Right.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain