|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 12:12 am Post subject: |
|
|
Bill,
You posted: Quote: | There's disk cache, and there is disk cache....
Yes, Windows is an animal all to its own. |
My experience of Windows 7 is that the disk cacheing works very well. It is much improved from XP. What sort of animal were you considering ?
My suggestion is that you do not use the "share=" option at all as depending on your access rights for the disk/directory you are using, it is a problem you don't need to introduce. If you are wanting to do inter-process locking, do it on a small file, not one that has large data transfers.
Another possible explanation for the times observed is when and how often the disk cache is being flushed to the disk. This may explain the case of write delays, as the cache may be flushed after each write.
When things are working well, the only flush takes place when the file is closed, although this is not always observed from the results.
I have a disk I/O test program for direct access files, although it typically uses larger blocks. The test sequence is:
- Open file
- Write N blocks
- Read N blocks
- Write N/10 blocks randomly
- Read N/10 blocks randomly
- Close file
I have 3 file access libraries:
- Standard Fortran
- My variable block size random access library (based on Fortran with extra buffers)
- File access library based on FTN95 file manipulation routines (or ifort routines)
I have tested this for a range of N for file sizes of 1k up to 3 x installed memory.
I have found that:
- Standard Fortran works as well as available system libraries
- There was a significant improvement in disk cache from XP to Win 7
- Disk flushing does not always occur on CLOSE !!
- for medium size files that can fit in the disk cache (say less than 6gb on my 8gb pc) disk cache can be a good substitute for a SSD, although they offer more flexible performance improvements.
- Cache performance is a function of other activities on the disk.
I have not tested share= alternatives, as the purpose of the tests was to identify ways of improving large data transfers.
I would expect that the problem you are observing is due to other factors and not FTN95 I/O performance.
John |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Mon Jan 26, 2015 1:30 am Post subject: |
|
|
Here is the test code I used, should you desire to replicate my tests on your machine and share the results.
Code: | !FTN95 application...
PROGRAM main
integer print_every
integer failed_open,failed_delete,failed_close,failed_write
character iorecord(194)
character*8 ddate,oper(6),share(5)
character*10 ttime
character*5 zzone
integer values(8),stest
character*20 access(6),form(6),status(6)
data status/'replace','old', 'old', 'replace', 'old', 'old'/
data access/'direct', 'direct','direct','sequential','sequential','sequential'/
data form/6*'unformatted'/
data oper/ 'write', 'write', 'read', 'write', 'write', 'read'/
data share/'denynone','denyrw','denywr','denyrd','compat'/
! Test program to open a unformatted direct access file, then write several records
! then close it and try again. Each failure to open will be logged along with the error code and date/time
! a 2 second wait will be done, then re-try.
!
! The first time, we'll delete the file, then create as a new, then old from then on
!
call date_and_time(ddate,ttime,zzone,values)
print *,"Starting the test at: ",ddate(1:8),' ',ttime(1:10)
max_recs=1000
do stest=1,5 !share
do jtest=1,6
open(unit=15,file='testfile.dat',access=access(jtest),iostat=icode,err=12000,&
form=form(jtest),recl=194,status=status(jtest),share=share(stest))
! the READ tests require that the file exists, so change 'replace' to 'old'
start_loop = high_res_clock@(.true.)
do 10000 i=1,max_recs
call randomfile(iorecord,194) ! this is always left in to even out the loop timing
!This next line must change to reflect read or write and rec= if needed
go to (1000,1000,2000,3000,3000,4000),jtest
1000 continue
write(15,rec=i,err=13000)iorecord
go to 10000
2000 continue
read(15,rec=i,err=13000,iostat=icheck)iorecord
go to 10000
3000 continue
write(15,err=13000)iorecord
go to 10000
4000 continue
read(15,err=13000)iorecord
go to 10000
10000 continue
end_loop = high_res_clock@(.false.)
print *,oper(jtest),max_recs,' records took ',end_loop-start_loop,'For access=',trim(access(jtest)),&
' format=',trim(form(jtest)),' status=',trim(status(jtest)),' share=',trim(share(stest))
close(unit=15)
call sleep1@(2.)
end do ! jtest
end do ! stest
pause
stop
13000 continue
print *,"io error",icheck
stop
12000 continue
print *,"open error",icode
stop
END PROGRAM main
subroutine randomfile(iorecord,length)
character*1 iorecord(length)
do i=1,length
iorecord=char(int(255.*random@()))
end do
return
end
|
|
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Mon Jan 26, 2015 1:34 am Post subject: |
|
|
Paul, it would be useful (to me, at least) to know how FTN95 opens a file in each of the available SHARE= modes. Right now, I can only guess. I might be able to find something with this small bit of detailed knowledge, perhaps even able to replicate in another language to identify the root cause. The way I figure it, if I found this, perhaps others have the same problem. And, if there is a root cause, it can be addressed (or not, as the case might be).
Rather than to say "Don't do it this way", perhaps the proper answer is "If you do it this way AND you get these kinds of results...". |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 5:22 am Post subject: |
|
|
Bill,
I ran your test
on Windows 7 Home Premium, Service Pack 1
i5-2300
921 GB partition of 2Tb HDD
in directory c:\temp\forum
ftn95 bill_file_io /-imp /lgo >zz
Code: | [FTN95/Win32 Ver. 7.10.0 Copyright (c) Silverfrost Ltd 1993-2014]
NO ERRORS [<MAIN> FTN95/Win32 v7.10.0]
NO ERRORS [<RANDOMFILE> FTN95/Win32 v7.10.0]
Creating executable: c:\temp\forum\lgotemp@.exe
Program entered
Starting the test at: 20150126 153114.426
write 1000 rec 1.49023 sec; For ac=direct fo=unformatted st=replace sh=denynone
write 1000 rec 1.63867 sec; For ac=direct fo=unformatted st=old sh=denynone
read 1000 rec 1.07422 sec; For ac=direct fo=unformatted st=old sh=denynone
write 1000 rec 0.982422 sec; For ac=sequential fo=unformatted st=replace sh=denynone
write 1000 rec 0.978516 sec; For ac=sequential fo=unformatted st=old sh=denynone
read 1000 rec 0.976563 sec; For ac=sequential fo=unformatted st=old sh=denynone
write 1000 rec 0.982422 sec; For ac=direct fo=unformatted st=replace sh=denyrw
write 1000 rec 0.972656 sec; For ac=direct fo=unformatted st=old sh=denyrw
read 1000 rec 0.964844 sec; For ac=direct fo=unformatted st=old sh=denyrw
write 1000 rec 0.978516 sec; For ac=sequential fo=unformatted st=replace sh=denyrw
write 1000 rec 0.994141 sec; For ac=sequential fo=unformatted st=old sh=denyrw
read 1000 rec 0.986328 sec; For ac=sequential fo=unformatted st=old sh=denyrw
write 1000 rec 0.978516 sec; For ac=direct fo=unformatted st=replace sh=denywr
write 1000 rec 0.998047 sec; For ac=direct fo=unformatted st=old sh=denywr
read 1000 rec 0.974609 sec; For ac=direct fo=unformatted st=old sh=denywr
write 1000 rec 0.980469 sec; For ac=sequential fo=unformatted st=replace sh=denywr
write 1000 rec 0.974609 sec; For ac=sequential fo=unformatted st=old sh=denywr
read 1000 rec 0.992188 sec; For ac=sequential fo=unformatted st=old sh=denywr
write 1000 rec 1.51563 sec; For ac=direct fo=unformatted st=replace sh=denyrd
write 1000 rec 1.56250 sec; For ac=direct fo=unformatted st=old sh=denyrd
read 1000 rec 1.08008 sec; For ac=direct fo=unformatted st=old sh=denyrd
write 1000 rec 0.980469 sec; For ac=sequential fo=unformatted st=replace sh=denyrd
write 1000 rec 0.974609 sec; For ac=sequential fo=unformatted st=old sh=denyrd
read 1000 rec 0.978516 sec; For ac=sequential fo=unformatted st=old sh=denyrd
write 1000 rec 1.53906 sec; For ac=direct fo=unformatted st=replace sh=compat
write 1000 rec 1.50000 sec; For ac=direct fo=unformatted st=old sh=compat
read 1000 rec 1.08008 sec; For ac=direct fo=unformatted st=old sh=compat
write 1000 rec 0.974609 sec; For ac=sequential fo=unformatted st=replace sh=compat
write 1000 rec 0.984375 sec; For ac=sequential fo=unformatted st=old sh=compat
read 1000 rec 0.976563 sec; For ac=sequential fo=unformatted st=old sh=compat
***Pause:
Enter system command or press ENTER key to restart: |
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 9:14 am Post subject: |
|
|
Bill,
I changed randomfile to:
do i=1,length
iorecord(i)=char(int(255.*random@()))
end do
I also tidied up the formats and used SYSTEM_CLOCK for timing. I got the following results.
Code: | [FTN95/Win32 Ver. 7.10.0 Copyright (c) Silverfrost Ltd 1993-2014]
NO ERRORS [<MAIN> FTN95/Win32 v7.10.0]
NO ERRORS [<RANDOMFILE> FTN95/Win32 v7.10.0]
NO ERRORS [<ELAPSE_TIME> FTN95/Win32 v7.10.0]
Creating executable: c:\temp\forum\lgotemp@.exe
Program entered
Starting the test at: 20150126 190544.999
write 1000 rec 0.4375 sec; For ac=direct fo=unformatted st=replace sh=denynone
write 1000 rec 0.4336 sec; For ac=direct fo=unformatted st=old sh=denynone
read 1000 rec 0.0859 sec; For ac=direct fo=unformatted st=old sh=denynone
write 1000 rec 0.0156 sec; For ac=sequential fo=unformatted st=replace sh=denynone
write 1000 rec 0.0234 sec; For ac=sequential fo=unformatted st=old sh=denynone
read 1000 rec 0.0234 sec; For ac=sequential fo=unformatted st=old sh=denynone
write 1000 rec 0.0156 sec; For ac=direct fo=unformatted st=replace sh=denyrw
write 1000 rec 0.0195 sec; For ac=direct fo=unformatted st=old sh=denyrw
read 1000 rec 0.0078 sec; For ac=direct fo=unformatted st=old sh=denyrw
write 1000 rec 0.0117 sec; For ac=sequential fo=unformatted st=replace sh=denyrw
write 1000 rec 0.0078 sec; For ac=sequential fo=unformatted st=old sh=denyrw
read 1000 rec 0.0117 sec; For ac=sequential fo=unformatted st=old sh=denyrw
write 1000 rec 0.0156 sec; For ac=direct fo=unformatted st=replace sh=denywr
write 1000 rec 0.0195 sec; For ac=direct fo=unformatted st=old sh=denywr
read 1000 rec 0.0117 sec; For ac=direct fo=unformatted st=old sh=denywr
write 1000 rec 0.0078 sec; For ac=sequential fo=unformatted st=replace sh=denywr
write 1000 rec 0.0117 sec; For ac=sequential fo=unformatted st=old sh=denywr
read 1000 rec 0.0078 sec; For ac=sequential fo=unformatted st=old sh=denywr
write 1000 rec 0.4180 sec; For ac=direct fo=unformatted st=replace sh=denyrd
write 1000 rec 0.4258 sec; For ac=direct fo=unformatted st=old sh=denyrd
read 1000 rec 0.0898 sec; For ac=direct fo=unformatted st=old sh=denyrd
write 1000 rec 0.0156 sec; For ac=sequential fo=unformatted st=replace sh=denyrd
write 1000 rec 0.0117 sec; For ac=sequential fo=unformatted st=old sh=denyrd
read 1000 rec 0.0313 sec; For ac=sequential fo=unformatted st=old sh=denyrd
write 1000 rec 0.4023 sec; For ac=direct fo=unformatted st=replace sh=compat
write 1000 rec 0.4297 sec; For ac=direct fo=unformatted st=old sh=compat
read 1000 rec 0.0859 sec; For ac=direct fo=unformatted st=old sh=compat
write 1000 rec 0.0156 sec; For ac=sequential fo=unformatted st=replace sh=compat
write 1000 rec 0.0195 sec; For ac=sequential fo=unformatted st=old sh=compat
read 1000 rec 0.0313 sec; For ac=sequential fo=unformatted st=old sh=compat
|
These results now show a difference for different share options, but not as dramatic as before.
John |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 10:19 am Post subject: |
|
|
Bill,
I did another test which is useful to compare with the previous by: - increased the record size to 1940
- introduced a test for no use of share=
The results are:
Code: |
[FTN95/Win32 Ver. 7.10.0 Copyright (c) Silverfrost Ltd 1993-2014]
0011) real elapse_time, start_open, start_loop, end_loop
WARNING - 242: Variable START_OPEN has been given a value but never used
NO ERRORS, 1 WARNING [<MAIN> FTN95/Win32 v7.10.0]
NO ERRORS [<RANDOMFILE> FTN95/Win32 v7.10.0]
NO ERRORS [<DELETE_FILE> FTN95/Win32 v7.10.0]
NO ERRORS [<ELAPSE_TIME> FTN95/Win32 v7.10.0]
Creating executable: c:\temp\forum\lgotemp@.exe
Program entered
Starting the test at: 20150126 201205.726
for testfile1.dat
testfile1.dat deleted
WRITE 1000 rec 0.055 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=
WRITE 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=
READ 1000 rec 0.051 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=
testfile1.dat deleted
WRITE 1000 rec 0.070 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=
WRITE 1000 rec 0.063 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=
READ 1000 rec 0.074 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=
DENYNONE for testfile2.dat
testfile2.dat deleted
WRITE 1000 rec 0.531 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=DENYNONE
WRITE 1000 rec 0.539 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYNONE
READ 1000 rec 0.141 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYNONE
testfile2.dat deleted
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=DENYNONE
WRITE 1000 rec 0.074 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYNONE
READ 1000 rec 0.082 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYNONE
DENYRW for testfile3.dat
testfile3.dat deleted
WRITE 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=DENYRW
WRITE 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYRW
READ 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYRW
testfile3.dat deleted
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=DENYRW
WRITE 1000 rec 0.070 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYRW
READ 1000 rec 0.074 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYRW
DENYWR for testfile4.dat
testfile4.dat deleted
WRITE 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=DENYWR
WRITE 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYWR
READ 1000 rec 0.070 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYWR
testfile4.dat deleted
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=DENYWR
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYWR
READ 1000 rec 0.063 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYWR
DENYRD for testfile5.dat
testfile5.dat deleted
WRITE 1000 rec 0.797 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=DENYRD
WRITE 1000 rec 0.621 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYRD
READ 1000 rec 0.152 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=DENYRD
testfile5.dat deleted
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=DENYRD
WRITE 1000 rec 0.090 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYRD
READ 1000 rec 0.074 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=DENYRD
|
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 10:21 am Post subject: |
|
|
ctd.
Code: | COMPAT for testfile6.dat
testfile6.dat deleted
WRITE 1000 rec 0.578 sec; For ac=DIRECT fo=UNFORMATTED st=REPLACE sh=COMPAT
WRITE 1000 rec 0.602 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=COMPAT
READ 1000 rec 0.207 sec; For ac=DIRECT fo=UNFORMATTED st=OLD sh=COMPAT
testfile6.dat deleted
WRITE 1000 rec 0.066 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=REPLACE sh=COMPAT
WRITE 1000 rec 0.074 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=COMPAT
READ 1000 rec 0.070 sec; For ac=SEQUENTIAL fo=UNFORMATTED st=OLD sh=COMPAT
|
Fixing call randomfile now produces more expected performance.
The results also show that omitting SHARE= can improve the direct performance.
Sequential access is somewhat faster with the SHARE= options.
Is there a need for this file access management ?
You should try different combinations of rec_len and num_rec and see how the run times scale up, identifying cache usage.
The following is the latest test program I generated, where I tried to provide more consistent OPEN options. ( still not complete !!)
Code: | !FTN95 application...
PROGRAM main
! integer print_every
! integer failed_open,failed_delete,failed_close,failed_write
integer, parameter :: rec_len = 1940
integer max_recs, stest, jtest, i, icode, icheck
character file_name*80
character iorecord(rec_len)*1
character ddate*8, ttime*10, zzone*5
integer values(8)
real elapse_time, start_open, start_loop, end_loop
external elapse_time
!
character share(6)*8, oper(6)*6, access(6)*10, form(6)*11, status(6)*7
DATA OPER /'WRITE', 'WRITE', 'READ', 'WRITE', 'WRITE', 'READ'/
DATA STATUS /'REPLACE','OLD', 'OLD', 'REPLACE', 'OLD', 'OLD'/
DATA ACCESS /'DIRECT', 'DIRECT','DIRECT','SEQUENTIAL','SEQUENTIAL','SEQUENTIAL'/
DATA FORM /6*'UNFORMATTED'/
DATA SHARE /' ', 'DENYNONE', 'DENYRW', 'DENYWR', 'DENYRD', 'COMPAT'/
! Test program to open a unformatted direct access file, then write several records
! then close it and try again. Each failure to open will be logged along with the error code and date/time
! a 2 second wait will be done, then re-try.
!
! The first time, we'll delete the file, then create as a new, then old from then on
!
call date_and_time(ddate,ttime,zzone,values)
print *,"Starting the test at: ",ddate(1:8),' ',ttime(1:10)
!
max_recs=1000
!
do stest=1,6 ! share
write (file_name, fmt='(a,i0,a)') 'testfile',stest,'.dat'
print *," "
print *," ",share(stest),' for ', trim (file_name)
do jtest=1,6
if ( jtest==1 .or. jtest==4) call delete_file (file_name)
start_open = elapse_time ()
if ( share(stest) == ' ') then
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
recl = rec_len )
else if ( access(jtest) == 'DIRECT' ) then
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
recl = rec_len, &
share = share(stest) )
else
|
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 10:38 am Post subject: |
|
|
.ctd/
Code: | else
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
share = share(stest) )
end if
! the READ tests require that the file exists, so change 'replace' to 'old'
start_loop = elapse_time ()
do i=1,max_recs
call randomfile (iorecord, rec_len) ! this is always left in to even out the loop timing
!This next line must change to reflect read or write and rec= if needed
select case (jtest) ! go to (1000,1000,2000,3000,3000,4000),jtest
case (1:2) ! write i
write (15, rec=i, err=13000, iostat=icheck) iorecord
case (3) ! read i
read (15, rec=i, err=13000, iostat=icheck) iorecord
case (4:5) ! write s
write (15, err=13000, iostat=icheck) iorecord
case (6) ! read s
read (15, err=13000, iostat=icheck) iorecord
end select
end do
end_loop = elapse_time ()
write (*,11) oper(jtest),max_recs,' rec ', &
end_loop-start_loop, ' sec; For', &
' ac=',access(jtest), &
' fo=',form(jtest), &
' st=',status(jtest), &
' sh=',share(stest)
11 format (a,i0, a,f0.3,a, 4(a,a) )
close (unit = 15, iostat = icode)
call sleep1@ (2.)
end do ! jtest
end do ! stest
! pause
stop
13000 continue
print *,"io error during accessing file", icheck
stop
12000 continue
print *,"open error", icode
stop
END PROGRAM main
subroutine randomfile (iorecord, length)
integer length, i
character iorecord(length)*1
do i=1,length
iorecord(i) = char(int(255.*random@()))
end do
return
end
subroutine delete_file (file_name)
character file_name*(*)
integer icode
!
open (unit = 15, &
file = file_name, &
status = 'UNKNOWN', &
iostat = icode )
!
close (unit = 15, &
status = 'DELETE', &
iostat = icode )
!
if ( icode == 0 ) then
write (*,*) trim (file_name),' deleted'
else
write (*,*) '### Unable to delete ',trim (file_name),' : check status !!'
end if
end subroutine delete_file
real function elapse_time ()
integer*8 clock, clock_rate
call system_clock ( clock, clock_rate )
elapse_time = dble (clock) / dble (clock_rate)
end function elapse_time
|
I hope this helps.
I'd be interested if you identify the problem combinations of ACCESS="DIRECT' and SHARE='xxx'
You should see that larger files do not have a huge time penalty, especially when you can skip cache buffering by reducing the number of CLOSE then OPEN operations.
John
ps: there should be an option for larger posts when required !! (or attachments) |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 12:19 pm Post subject: |
|
|
Bill,
I have produced a test program that tests more alternatives of size and disk buffering.
If you watch the program run, using windows explorer, you will see which share= options are continually updating the disk for access='direct'. Other options show the use of the disk cache with fewer changes to the stored file.
Sequential access does not appear to work this way and might not not support multiple read/write.
I tried to reduce flushing by minimising open/close, but that does not appear to be working as I hoped.
The latest test code is: Code: | ! program to test share= performance
!
call do_test ( 194, 1000, .false. )
call do_test ( 2048, 2000, .false. )
call do_test ( 2048*8, 10000, .false. )
call do_test ( 2048*8, 10000, .true. )
end
!FTN95 application...
subroutine do_test (rec_len, max_recs, Minimise_Close)
!
logical :: Minimise_Close
integer :: rec_len
integer :: max_recs
!
character iorecord(rec_len)*1
!
logical :: open_file, close_file
!
character file_name*80
integer stest, jtest, i, icode, icheck
!
character share(6)*8, oper(6)*6, access(6)*10, form(6)*11, status(6)*7
DATA OPER /'WRITE', 'WRITE', 'READ', 'WRITE', 'WRITE', 'READ'/
DATA STATUS /'REPLACE','OLD', 'OLD', 'REPLACE', 'OLD', 'OLD'/
DATA ACCESS /'DIRECT', 'DIRECT','DIRECT','SEQUENTIAL','SEQUENTIAL','SEQUENTIAL'/
DATA FORM /6*'UNFORMATTED'/
DATA SHARE /' ', 'DENYNONE', 'DENYRW', 'DENYWR', 'DENYRD', 'COMPAT'/
!
character ddate*8, ttime*10, zzone*5
integer values(8)
real elapse_time, start_open, start_loop, end_loop, mb_sec
external elapse_time
! Test program to open a unformatted direct access file, then write several records
! then close it and try again. Each failure to open will be logged along with the error code and date/time
! a 2 second wait will be done, then re-try.
!
! The first time, we'll delete the file, then create as a new, then old from then on
!
call date_and_time(ddate,ttime,zzone,values)
print *,"Starting the test at: ",ddate(1:8),' ',ttime(1:10),' for',max_recs,' records length =',rec_len
!
do stest=1,6 ! share
write (file_name, fmt='(a,i0,a)') 'testfile',stest,'.dat'
print *," "
print *," ",share(stest),' for ', trim (file_name)
do jtest=1,6
!
if ( jtest==1 .or. jtest==4) call delete_file (file_name)
if ( minimise_close ) then
open_file = ( jtest == 1 .or. jtest == 4)
close_file = ( jtest == 3 .or. jtest == 6)
else
open_file = .true.
close_file = .true.
end if
!
start_open = elapse_time ()
if ( open_file ) then
if ( share(stest) == ' ') then ! omit share =
if ( access(jtest) == 'DIRECT' ) then
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
recl = rec_len )
else
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest) )
end if
else ! include share =
|
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 12:21 pm Post subject: |
|
|
.ctd/ Code: | else ! include share =
if ( access(jtest) == 'DIRECT' ) then
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
recl = rec_len, &
share = share(stest) )
else
open (unit = 15, &
file = file_name, &
iostat = icode, &
err = 12000, &
access = access(jtest), &
form = form(jtest), &
status = status(jtest), &
share = share(stest) )
end if
end if
write (*,*) 'file opened'
else if ( access(jtest) /= 'DIRECT' ) then
rewind ( unit = 15 )
end if
! the READ tests require that the file exists, so change 'replace' to 'old'
!
start_loop = elapse_time ()
do i=1,max_recs
call randomfile (iorecord, rec_len) ! this is always left in to even out the loop timing
!This next line must change to reflect read or write and rec= if needed
select case (jtest) ! go to (1000,1000,2000,3000,3000,4000),jtest
case (1:2) ! write i
write (15, rec=i, err=13000, iostat=icheck) iorecord
case (3) ! read i
read (15, rec=i, err=13000, iostat=icheck) iorecord
case (4:5) ! write s
write (15, err=13000, iostat=icheck) iorecord
case (6) ! read s
read (15, err=13000, iostat=icheck) iorecord
end select
end do
end_loop = elapse_time ()
!
mb_sec = real(max_recs)*real(rec_len) / (end_loop-start_loop) / 1024. / 1024.
write (*,11) oper(jtest),max_recs,' rec ', &
end_loop-start_loop, ' sec; For', &
' ac=',access(jtest), &
' fo=',form(jtest), &
' st=',status(jtest), &
' sh=',share(stest), &
mb_sec
11 format (a,i0, a,f0.3,a, 4(a,a), f7.3,' Mb/sec' )
!
if ( close_file ) then
close (unit = 15, iostat = icode)
write (*,*) 'file closed'
call sleep1@ (2.)
end if
!
end do ! jtest
end do ! stest
! pause
return
13000 continue
print *,"io error during accessing file", icheck
stop
12000 continue
print *,"open error", icode
stop
END subroutine do_test
subroutine randomfile (iorecord, length)
integer length, i
character iorecord(length)*1
do i=1,length
iorecord(i) = char(int(255.*random@()))
end do
return
end
|
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jan 26, 2015 12:26 pm Post subject: |
|
|
.ctd 2/ Code: | subroutine delete_file (file_name)
character file_name*(*)
integer icode
!
open (unit = 15, &
file = file_name, &
status = 'UNKNOWN', &
iostat = icode )
!
close (unit = 15, &
status = 'DELETE', &
iostat = icode )
!
if ( icode == 0 ) then
write (*,*) trim (file_name),' deleted'
else
write (*,*) '### Unable to delete ',trim (file_name),' : check status !!'
end if
end subroutine delete_file
real function elapse_time ()
integer*8 clock, clock_rate
call system_clock ( clock, clock_rate )
elapse_time = dble (clock) / dble (clock_rate)
end function elapse_time
|
It does demonstrate performance changes on my HDD, so hopefully it can show changes on your disk alternatives for the various share= options.
I hope the trend is consistent with the expected file access attributes.
John |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Mon Jan 26, 2015 5:12 pm Post subject: |
|
|
John,
WOW, you certainly have gone over and above what I could have ever expected, and I am very grateful! You put a lot of effort into this.
If I could state in one sentence what you've found: The use of SHARE has an effect on the performance, and certain SHARE options have a bigger effect than others. There's a lot more you did here, but would that be accurate in your view?
Yes, the original code was inefficient (i.e. use of random()). The original thought there was that if the Antivirus was triggering on some random data, perhaps this would show it. After I was able to identify and workaround the odd IOSTAT values (10005 and 10002) when files were opened, the need for randomized data actually went away. But, left it for consistency.The random() was left in for the reads for timing comparisons.
I only perform one open/close for each block of records, so I am curious about your comment (Mon Jan 26, 2015 3:38 am MST).
It is interesting that the SHARE would cause a difference in performance, and while your numbers are certainly faster than mine it still begs the question: Why?
As far as bigger records, no, not possible. My software has a legacy that dates back to the early 80's, when it was run on machines as simple as S-100 bus, CP/M. File size is set by the variables required. Would that I could change the sizes or formats!! It would make life so much easier. Some of the files created in those early days are still in use today, just much bigger!
When some of the users started using a networking environment in the mid 90's, the question of access restrictions came up. With multiple users on individual machines, sometimes EXCLUSIVE access is required when updating the master files (most of which are binary, unformatted, direct), while in most cases, simple READ access is needed. As well, there are some sequential, formatted files that can be affected. So, yes, I do need to have the SHARE set appropriately, and the setting of this access is dependent on the file usage at the time, and the software asks for that access as needed when opening the file.
I hope to replicate your results on my primary machine later today. It will be an interesting comparison.
I am looking at "perfmon" to do some more detailed looks at the transfers and IO operations counts associated with these various operations. Once I get that up and running (and a little more time), I'll share it here. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Jan 27, 2015 2:21 am Post subject: |
|
|
Bill,
I have now seen your problem !!
I transferred my latest test code to my notebook, which is running Windows 8.1. This OS must rival Vista as I find it an appalling downgrade from Windows 7.
I am getting huge delays on direct access files with some share= options. ( some cases 20sec, 40 sec and even 250 sec ! I'll update when the tests are complete.)
I am trying running in a normal DOS box then running as administrator. Both have big delays for direct access files. Must have something to do with directory access rights. As these delays occur while writing and not just when opening, there could be some incompatibility or tuning required with salflibc.dll and Win 8.1.
Not sure what the solution is, but certainly removing Windows 8.1 would be a good approach.
John |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Tue Jan 27, 2015 3:12 am Post subject: |
|
|
John, perhaps removing 8.1 might be a bit premature. It is nice to see that it can happen to others!
I do suspect it has something to do with policies or permissions, but I am at a loss to know. I'm not a SYSADMIN!
Bill |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue Jan 27, 2015 5:14 pm Post subject: |
|
|
I have been using W8.0 since May 2013, and W8.1 since Dec 2013. While the tiles interface is correctly worthy of ridicule and condemnation, the underlying OS is solid and competent. I do most of my work at the command line, and have a third party Start program to make the system behave similarly to W7.
I took John's program of Jan 26, 2015 11:19 am, and modified it as follows.
1. Removed the call to sleep@.
2. Added a call to delete_file after the END DO !jtest
3. Used CPU_TIME for timing instead of SYSTEM_CLOCK.
These changes allow the code to be run on a ramdisk using FTN95 and Intel Fortran. I see none of the problems of slowdown that others have mentioned, indicating that "something else" is the culprit. With FTN95 I get speeds of about 30 MB/s, for all except the runs with small files, where the speed can go down to 10 MB/s or less. With Intel Fortran, the corresponding speeds are 45 MB/s and 12 MB/s. (These "speeds" are as reported by the program, on a laptop with an i5-4200U CPU)
Once you set up a comfortable program development environment under it, you will not complain about W8x. In a multiprocessing environment, I/O to files with shared access is subject to many influences in addition to hardware, OS and compiler brand differences. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|