- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
the small program below yields a stunning writing speed difference when compiled with ifort and gfortran
program test implicit none real :: t1,t2 integer(8) :: j !!integer(8), allocatable :: r(:) !!allocate(r(10000000),source=int(0,kind=8)) real(8), allocatable :: r(:) allocate(r(10000000),source=0.0D0) open(100,file="out.csv",action="write",status="replace",form="formatted") call cpu_time(t1) do j=1,size(r) write(100,*) r(j) end do call cpu_time(t2); write(*,*) t2-t1 close(100) end program test
gfortran wrote the integer version in about 1.1 seconds, the real version in about 4.5 seconds. Ifort versions 17.08, 19.05 and 19.1.1 needed 11 seconds and 12 seconds, respectively. Is just what it is or is there a bug somewhere.
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your WRITE is list-directed, so the format as well the length of the output file are implement-dependent. Ifort write 10 million lines with
0.000000000000000E+000
whereas Gfortran writes
0.0000000000000000
As you probably are already aware, it would be much faster to write the whole array with a single WRITE statement instead of WRITE in a DO loop.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
thank for your explanation ...... if that's what it is that's a bit poor. Note that biggest speed differences are for integer, not for real.
The speed differences of factor 10 for integer write remain even without a do loop
Further, no do-look will cause gfortran to write a single line of output, ifort to write 3Mio lines. Differences in file format
due to compiler change are not exceptable when the programs are part of a pipeline. So the do loop is a must.
cheers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you wish to drill down into the causes, you may try specifying the format yourself, look at differences in buffer sizes, compare internal to decimal conversion algorithms in the RTL, etc. For using the timings as a metric, it would be better to use, say, 1.234567890123456d0, instead of the special number 0.0d0.
In a real application in which I/O is not so dominant as in this tiny example, even a factor of 10 variation in I/O time may not be significant in comparison to, say, FEA computations that precede the I/O.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
just figured out how to induce the line break in the no-doloop one-liner via format. Unfortunately that increased the speed difference between gfortran and ifort to factor 20 (as in ifort no do-loop and do-loop are the same)!! However, thank for you comments but I won't drill any further. Maybe intel pics this up for future improvements.
cheers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you confirm which version of gFortran you used, as there has been a history of improvement for gFortran text write speed.
I can not reproduce your "gfortran wrote the integer version in about 1.1 seconds", although it can depend on both compiler and disk type.
I achieved 8.3 seconds for 8-byte integers on i7-8700K with gFortran 8.3.0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I used gfortran 10.1.0 on an Arch Linux System with kernel version 5.2.7. The disk is a Samsung 970 EVO Plus 2TB M.2 PCIe SSD.
cheers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program test implicit none real :: t1,t2 integer(8) :: j !!integer(8), allocatable :: r(:) !!allocate(r(10000000),source=int(0,kind=8)) real(8), allocatable :: r(:) allocate(r(10000000),source=0.0D0) open(100,file="out.csv",action="write",status="unknown") call cpu_time(t1) write(*,*) t1 do j=1,size(r) write(100,*) r(j) end do call cpu_time(t2); write(*,*) t2-t1 close(100) end program test
I amended your program slightly and ran it on a corei5 with a SAMSUMG EVO drive -- you create a file that is 247 MB,
1. you cannot open a file this big in EXCEL
2. It took 233 seconds to write reals to a SAMSUNG EVO 960 -- I think
3. I copied it between a SAMSUNG EVO and an M2 and that only moved at 859MB/s
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Scott L.
awesome hint. That did the trick. Thanks a lot.
cheers
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page