Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

which is efficient


Hi

This is the code

DO  J1=1,SS
    DO  I1=1,TT
      DO  ISUMT3=1,MA
        SUMGMT(I1,J1,ISUMT3)=0.0
      END DO
    END DO
  END DO

i can write the following code in FORTRAN 90 as

SUMGMT(1:TT,1:SS,1:ISUMT3) = 0.0

now my question is which one is the efficeint way to do it?

I think i know the answer, the second way is more efficient.

Am i right ?  And if yes how do i prove it? How can i prove this with
this simple code that the second one is efficient ?

regards

Whether you are right or not depends on what compiler you are using,
what optimization switches you are using, and what sort of computer
you're running the compiled code on.

It is also likely to depend on whether this is the entirety of the
array, or only part of it.  And on whether or not the compiler knows the
answer to that question when it's compiling this particular code.  (For
example, if this is in a subroutine that gets an assumed-shape array, it
may not know.)

And it's also likely to be important that that's 0.0 and not some other
number, too.  On some systems, setting a large swath of memory to all
zero bits is faster than setting it to some particular value.

In any case, the truth of the matter is that, in order to get any really
meaningful answer to this question, you need to test it yourself.  Write
a program that does one of these bits of code over and over, thousands
of times.  Time how long it takes.  Do the same with the other code, and
compare the results.  Alternately, compile the two codes using a
compiler switch which dumps out the assembly-level instructions it
creates, and look at them and calculate which one takes more time.  (You
should probably do the latter anyway, just to make sure that the
compiler isn't optimizing things entirely away.)

However, I will bet that, for things this simple, any reasonably good
optimizing compiler will realize that these two bits of code do exactly
the same thing, and thus will produce exactly the same result for either
one.

And thus the right answer is: Use the second one, because it's easier to
read.

Meanwhile, I think there's a more important question: Does this even
matter?  If your program is written in such a way that it spends a
significant amount of time setting large arrays to zero, then chances
are reasonably good that have an algorithm that's wasting time zeroing
arrays that don't need to be zeroed, and you should fix the algorithm
instead.  And, if your program doesn't spend a lot of time zeroing out
the arrays, then it doesn't make a hill of beans worth of difference if
one method is 2% faster than the other.

- Brooks

--
The "bmoses-nospam" address is valid; no unmunging needed.

Possibly so, since you would have to turn on a loop-nest optimization
option to get good performance with the first version.  Did you mean
SUMGMT(1:TT,1:SS,1:MA) ?
The answer certainly depends on circumstances which go beyond the
Fortran standard or the information presented here.

Most likely. The compiler can use the most efficient order to loop
through the array.

> Am i right ?  And if yes how do i prove it? How can i prove this with
> this simple code that the second one is efficient ?

You can try to check it, you cannot prove it. There is no garantee
that the compiler can not be smart enough to optimize your loops.

aeroguy <sukhbinder.si@gmail.com> wrote:
> DO  J1=1,SS
>     DO  I1=1,TT
>       DO  ISUMT3=1,MA
>         SUMGMT(I1,J1,ISUMT3)=0.0
>       END DO
>     END DO
>   END DO
> SUMGMT(1:TT,1:SS,1:ISUMT3) = 0.0
> now my question is which one is the efficeint way to do it?

It depends, but you should also try:

  DO  ISUMT3=1,MA
    DO  J1=1,SS
      DO  I1=1,TT
         SUMGMT(I1,J1,ISUMT3)=0.0
      END DO
    END DO
  END DO

--
pa at panix dot com

Almost certainly the second as presented, but that's only true because
you have order of your loop indices reversed.  If you get the loop
indices right (loop on the rightmost index first, then the middle, then
the left), it might be either.

> Am i right ?  And if yes how do i prove it? How can i prove this with
> this simple code that the second one is efficient ?

Profiling can do this.  Put each version in a subroutine, call it a lot
of times, be careful to have it be a situation where the compiler
doesn't get smart and optimize the whole thing out, and you should be
able to tell from the timing for the two subroutines.  You can also
manually time it with e.g. CPU_TIME.
On Apr 24, 11:38 pm, aeroguy <sukhbinder.si@gmail.com> wrote:

Just set SS, TT and MA to some reasonably large numbers so that the
execution time would be longe enough to ignore side effects and
measure what happens. I bet you won't see any difference. But you
might get a speed up if you use some sort of autoparalelizing and/or
vectorizing features of your compiler/processor.

Cheers,
Victor.

On Apr 25, 1:34 pm, Michel Olagnon <molag@ifremer-a-oter.fr> wrote:

Thnak you all for your answers and time. Well the code i am modifying
is setting lot of arrays to zeros. so i will look to change the
algorithm. Meanwhile i am not looking for any compiler optimisation.
What i want is is there some ways in which by some user techniques and
by using particular standards of FORTRAN one can get a optimised code
and thus easy the work of a coomplier as such.

I google and found lots of terms like loop interchange, loop tilting,
loop blocking, and many others. I want to know is this techniques
worth the effort.

i will now list a subroutine of the program, can you please suggest a
better, effecient way to remove/replace the GOTO jumble that it has:

SUBROUTINE iskokaro1 (j,mde,inl)
use wjans, only: lim1
use modul5,   only: sndi,ssrec
use modul29,  only: v29
use modul85,  only: noblm
use lmodul6,  only: un

INTEGER, INTENT(IN)                      :: j
INTEGER, INTENT(IN)                      :: mde
INTEGER, INTENT(IN OUT)                  :: inl
SAVE
DIMENSION x(20*(lim1+2))

INTEGER :: wjan,wjan0,wjan1,wjan2,blkno,filea,fileb
INTEGER :: filec

IF (inl == 0) GO TO 1
IF (inl > 1) GO TO 70
noblm=lim1
wjan=(noblm+2)*20
ssndi=j
IF (sndi == 0) sndi=1
wjan0=wjan/sndi-2
j1=1
j2=wjan0
wjan1=wjan0+1
wjan2=wjan0+2
jx=wjan2
nblk=0
blkno=1
kk=sndi
initl=1
iwrite=0
filea=un(10)
fileb=un(10)
REWIND filea
DO  k=1,kk
  DO  i=1,wjan2
    x((i-1)*kk+k)=0.
  END DO
END DO
DO  k=1,kk
  v29(k)=0.
END DO
RETURN
1 kya=mde
jj=j
IF (kya == 0) GO TO 3
IF (jj /= 1) GO TO 3
IF (iwrite == 1) GO TO 3
IF (initl == 1) GO TO 3
iwrite=1
fileb=un(13)
REWIND fileb
3 IF (jj >= j1) GO TO 25
nblk=MAX0(nblk,blkno)
IF (kya == 0) GO TO 20
initl=0
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (blkno == 1) GO TO 18
ssrec=jx
DO  k=1,kk
  WRITE (fileb) (x((i-1)*kk+k),i=1,ssrec)
END DO
IF (iwrite == 0) GO TO 10
REWIND filea
ii=filea
filea=fileb
fileb=ii
10 REWIND filea
DO  k=1,kk
  READ (filea) (x((i-1)*kk+k),i=1,wjan1)
END DO
j1=1
j2=x((wjan1-1)*kk+1)
blkno=1
18 jx=wjan2
RETURN
20 IF (blkno == 1) GO TO 18
GO TO 10
25 IF (jj > j2) GO TO 45
IF (kya == 0) GO TO 35
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (kya == 2) last=jx
35 jx=jj-j1+1
DO  k=1,kk
  v29(k)=x((jx-1)*kk+k)
END DO
RETURN
45 IF (kya == 0) GO TO 55
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (kya == 2) last=jx
IF (initl == 1) x((wjan1-1)*kk+1)=last-1
DO  k=1,kk
  WRITE (fileb) (x((i-1)*kk+k),i=1,wjan1)
END DO
IF (initl == 0) GO TO 55
jjj=jx-last+1
DO  jj=1,jjj
  jx=last+jj-1
  DO  k=1,kk
    x((jj-1)*kk+k)=x((jx-1)*kk+k)
  END DO
END DO
jx=jjj+1
55 j1=j1+x((wjan1-1)*kk+1)
j2=j1+wjan0-1
blkno=blkno+1
IF (initl == 1) RETURN
ii=wjan1
IF (blkno == nblk) ii=ssrec
DO  k=1,kk
  READ (filea) (x((i-1)*kk+k),i=1,ii)
END DO
IF (blkno == nblk) x((wjan1-1)*kk+1)=ssrec
j2=j1+x((wjan1-1)*kk+1)-1
GO TO 35
70 CONTINUE
IF (j == 1) THEN
  filec=un(20)
ELSE
  filec=un(33)
END IF
IF (inl == 2) THEN
  REWIND filec
  WRITE (filec) sndi,wjan0,wjan1,wjan2,nblk,ssrec
  DO  n=1,nblk
    ii=wjan1
    IF (n == nblk.AND.nblk > 1) ii=ssrec
    DO  k=1,kk
      IF (n > 1) READ (filea) (x((i-1)*kk+k),i=1,ii)
      WRITE (filec) (x((i-1)*kk+k),i=1,ii)
    END DO
  END DO
ELSE
  READ (filec) sndi,wjan0,wjan1,wjan2,nblk,ssrec
  kk=sndi
  initl=0
  iwrite=0
  filea=un(10)
  REWIND filea
  ssrec=0
  DO  n=1,nblk
    ii=wjan1
    IF (n == nblk.AND.nblk > 1) ii=ssrec
    ssrec=ssrec+ii-1
    DO  k=1,kk
      READ (filec) (x((i-1)*kk+k),i=1,ii)
      IF (nblk > 1) WRITE (filea) (x((i-1)*kk+k),i=1,ii)
    END DO
  END DO
END IF
REWIND filec
IF (nblk > 1) THEN
  GO TO 10
ELSE
  GO TO 18
END IF
RETURN
END SUBROUTINE iskokaro1

Because of the time gap, we cant't have live commenting on this post
but if you have question , please mention it will reply on next day.

thanks for your time and consideration

On Apr 25, 1:34 pm, Michel Olagnon <molag@ifremer-a-oter.fr> wrote:

Thnak you all for your answers and time. Well the code i am modifying
is setting lot of arrays to zeros. so i will look to change the
algorithm. Meanwhile i am not looking for any compiler optimisation.
What i want is is there some ways in which by some user techniques and
by using particular standards of FORTRAN one can get a optimised code
and thus easy the work of a coomplier as such.

I google and found lots of terms like loop interchange, loop tilting,
loop blocking, and many others. I want to know is this techniques
worth the effort.

i will now list a subroutine of the program, can you please suggest a
better, effecient way to remove/replace the GOTO jumble that it has:

SUBROUTINE iskokaro1 (j,mde,inl)
use wjans, only: lim1
use modul5,   only: sndi,ssrec
use modul29,  only: v29
use modul85,  only: noblm
use lmodul6,  only: un

INTEGER, INTENT(IN)                      :: j
INTEGER, INTENT(IN)                      :: mde
INTEGER, INTENT(IN OUT)                  :: inl
SAVE
DIMENSION x(20*(lim1+2))

INTEGER :: wjan,wjan0,wjan1,wjan2,blkno,filea,fileb
INTEGER :: filec

IF (inl == 0) GO TO 1
IF (inl > 1) GO TO 70
noblm=lim1
wjan=(noblm+2)*20
ssndi=j
IF (sndi == 0) sndi=1
wjan0=wjan/sndi-2
j1=1
j2=wjan0
wjan1=wjan0+1
wjan2=wjan0+2
jx=wjan2
nblk=0
blkno=1
kk=sndi
initl=1
iwrite=0
filea=un(10)
fileb=un(10)
REWIND filea
DO  k=1,kk
  DO  i=1,wjan2
    x((i-1)*kk+k)=0.
  END DO
END DO
DO  k=1,kk
  v29(k)=0.
END DO
RETURN
1 kya=mde
jj=j
IF (kya == 0) GO TO 3
IF (jj /= 1) GO TO 3
IF (iwrite == 1) GO TO 3
IF (initl == 1) GO TO 3
iwrite=1
fileb=un(13)
REWIND fileb
3 IF (jj >= j1) GO TO 25
nblk=MAX0(nblk,blkno)
IF (kya == 0) GO TO 20
initl=0
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (blkno == 1) GO TO 18
ssrec=jx
DO  k=1,kk
  WRITE (fileb) (x((i-1)*kk+k),i=1,ssrec)
END DO
IF (iwrite == 0) GO TO 10
REWIND filea
ii=filea
filea=fileb
fileb=ii
10 REWIND filea
DO  k=1,kk
  READ (filea) (x((i-1)*kk+k),i=1,wjan1)
END DO
j1=1
j2=x((wjan1-1)*kk+1)
blkno=1
18 jx=wjan2
RETURN
20 IF (blkno == 1) GO TO 18
GO TO 10
25 IF (jj > j2) GO TO 45
IF (kya == 0) GO TO 35
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (kya == 2) last=jx
35 jx=jj-j1+1
DO  k=1,kk
  v29(k)=x((jx-1)*kk+k)
END DO
RETURN
45 IF (kya == 0) GO TO 55
DO  k=1,kk
  x((jx-1)*kk+k)=v29(k)
END DO
IF (kya == 2) last=jx
IF (initl == 1) x((wjan1-1)*kk+1)=last-1
DO  k=1,kk
  WRITE (fileb) (x((i-1)*kk+k),i=1,wjan1)
END DO
IF (initl == 0) GO TO 55
jjj=jx-last+1
DO  jj=1,jjj
  jx=last+jj-1
  DO  k=1,kk
    x((jj-1)*kk+k)=x((jx-1)*kk+k)
  END DO
END DO
jx=jjj+1
55 j1=j1+x((wjan1-1)*kk+1)
j2=j1+wjan0-1
blkno=blkno+1
IF (initl == 1) RETURN
ii=wjan1
IF (blkno == nblk) ii=ssrec
DO  k=1,kk
  READ (filea) (x((i-1)*kk+k),i=1,ii)
END DO
IF (blkno == nblk) x((wjan1-1)*kk+1)=ssrec
j2=j1+x((wjan1-1)*kk+1)-1
GO TO 35
70 CONTINUE
IF (j == 1) THEN
  filec=un(20)
ELSE
  filec=un(33)
END IF
IF (inl == 2) THEN
  REWIND filec
  WRITE (filec) sndi,wjan0,wjan1,wjan2,nblk,ssrec
  DO  n=1,nblk
    ii=wjan1
    IF (n == nblk.AND.nblk > 1) ii=ssrec
    DO  k=1,kk
      IF (n > 1) READ (filea) (x((i-1)*kk+k),i=1,ii)
      WRITE (filec) (x((i-1)*kk+k),i=1,ii)
    END DO
  END DO
ELSE
  READ (filec) sndi,wjan0,wjan1,wjan2,nblk,ssrec
  kk=sndi
  initl=0
  iwrite=0
  filea=un(10)
  REWIND filea
  ssrec=0
  DO  n=1,nblk
    ii=wjan1
    IF (n == nblk.AND.nblk > 1) ii=ssrec
    ssrec=ssrec+ii-1
    DO  k=1,kk
      READ (filec) (x((i-1)*kk+k),i=1,ii)
      IF (nblk > 1) WRITE (filea) (x((i-1)*kk+k),i=1,ii)
    END DO
  END DO
END IF
REWIND filec
IF (nblk > 1) THEN
  GO TO 10
ELSE
  GO TO 18
END IF
RETURN
END SUBROUTINE iskokaro1

Because of the time gap, we cant't have live commenting on this post
but if you have question , please mention it will reply on next day.

thanks for your time and consideration

"aeroguy" <sukhbinder.si@gmail.com> wrote in message

news:1177564368.272312.142740@n15g2000prd.googlegroups.com...

> On Apr 25, 1:34 pm, Michel Olagnon <molag@ifremer-a-oter.fr> wrote:

[liberal editting]

On my server, it shows this message twice.  If this was your source, you
have a demonstrably subtle mind.  Did you post the message twice or did
Google do that for you?
--
WW

Go back to original compilable code and straighten that out before
inserting new f90 syntax.
Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc