Silverfrost Forums

Welcome to our forums

Slow writing to direct access file

4 Oct 2012 3:18 #10802

I am currently testing FTN95 v6.30, and I have found that writing to a direct access file is extremely slow (in fact is has been just as slow in previous versions - one has to go all the way back to v2.52 to get it real fast).

The test program below shows the problem: If compiled and linked with v6.30 it takes about 8 seconds on my computer (XP 32 bit) to write the file. But if I use a SALFLIBC.DLL v2.52 it takes just a split second (which is to be expected). I have also tried v2.54 and v5.10 - they are equally slow. The problem seems to lie in SALFLIBC.DLL.

Why are the newer versions so slow, and is there a way around this?

PROGRAM WRTEST

INTEGER, PARAMETER :: INTREC = 128 INTEGER, DIMENSION(1:INTREC) :: INTBUF

OPEN (91,FILE='WRTEST',ACCESS='DIRECT', & FORM='UNFORMATTED',RECL=512, & ACTION='WRITE',STATUS='REPLACE',IOSTAT=IOTAL)

IFILN=1; IPTR=0 PRINT *,'PRESS ENTER'; READ *

call cpu_time(t0)

DO I=1,100000 IPTR=IPTR+1 IF (IPTR>INTREC) THEN WRITE(91,REC=IFILN,IOSTAT=IOTAL) INTBUF IFILN=IFILN+1; IPTR=1 ENDIF INTBUF(IPTR)=I ENDDO

call cpu_time(t3) print *,'wrtest time',t3-t0

END PROGRAM WRTEST

4 Oct 2012 11:27 #10804

The problem is with your OPEN, using ACTION=WRITE. If you omit it or select ACTION=READWRITE, then all will be ok. It makes sense to me, as when you write to a defined point in a direct access file, it could be argued that it needs to read the last physical record for that logical record. There is no requirement to write the direct access file sequentially. I'm not sure what it is doing in those 9 seconds, but probably is a I/O interrupt of some form. You should probably check IOTAL, but it could be 0. Your program takes 9.3 seconds on my SSD drive, but only 0.0094 seconds with the ACCESS change. edit: I modified to better demonstrate the changed performance and report any possible errors.

PROGRAM WRTEST 
!
INTEGER, PARAMETER :: INTREC = 128 
INTEGER, DIMENSION(1:INTREC) :: INTBUF 
real*8 t0,t3
integer i, iptr, ifiln, iotal, kk
integer count0, count3, count_rate, count_max
!
do kk = 1,2
 if (kk==1) then
 OPEN (UNIT   = 91,             &
       FILE   = 'WRTEST',       &
       ACCESS = 'DIRECT',       & 
       FORM   = 'UNFORMATTED',  &
       RECL   = 512,            & 
       ACTION = 'WRITE',        &
       STATUS = 'REPLACE',      &
       IOSTAT = IOTAL) 
 else
 OPEN (UNIT   = 91,             &
       FILE   = 'WRTEST',       &
       ACCESS = 'DIRECT',       & 
!ZZ       FORM   = 'UNFORMATTED',  &
       RECL   = 512,            & 
!zz       ACTION = 'WRITE',        &
!zz       STATUS = 'REPLACE',      &
       IOSTAT = IOTAL) 
 end if
 write (*,*) 'File open; iostat=',iotal,kk
!
 IFILN=1; IPTR=0 
!zz PRINT *,'PRESS ENTER'; READ * 
!
 call cpu_time (t0) 
 call SYSTEM_CLOCK (count0, count_rate, count_max)
!
 DO I=1,100000 
   IPTR=IPTR+1 
   IF (IPTR>INTREC) THEN 
     WRITE(91,REC=IFILN,IOSTAT=IOTAL) INTBUF 
     if (iotal /=0) write (*,*) 'record=',ifiln,'  iostat=',iotal
     IFILN=IFILN+1; IPTR=1 
   ENDIF 
   INTBUF(IPTR)=I 
 ENDDO 
!
 call cpu_time(t3) 
 call SYSTEM_CLOCK (count3, count_rate, count_max)
 print *, ' wrtest cpu time', t3-t0 
 print *, ' wrtest elapse  ', real(count3-count0)/real(count_rate)
 print *, ' records written', ifiln
 print *, ' last IOTAL     ', IOTAL
 close (unit = 91,STATUS='delete')
end do
!
END PROGRAM WRTEST
9 Oct 2012 9:59 #10806

Hi John. Thanks for looking so thoroughly into this problem. It now works very well indeed.

Please login to reply.