flang
flang copied to clipboard
Unformatted I/O is slow compared to gfortran
This might be a fun one for someone to track down in the runtime.
When doing large amounts of unformatted reads and writes, flang is slower than gfortran (especially on reads).
We have an example program here which writes a lot of binary data and then reads it back in.
gfortran appears to be about twice as flang when reading the data.
When run on one of our x86 systems here, this is the kind of output I got (combining the output of the program with time) using gfortran 7.3.0 and Flang built with LLVM 9:
|----------------+------------+----------|
| Activity | gfortran | flang |
|----------------+------------+----------|
| write required | 9.09466076 | 10.37188 |
|----------------+------------+----------|
| read required | 6.24956703 | 14.33057 |
| read real | 18.795 | 29.205 |
| read user | 9.779 | 16.018 |
| read sys | 4.208 | 7.961 |
|----------------+------------+----------|
Here's the program that prints the time to write, then read, the file:
PROGRAM TEST_INPUT
IMPLICIT NONE
INTEGER X, Y, Z, MAX_X, MAX_Y, MAX_Z, ISOUR, IR, IT, ITIM
INTEGER*8 RATE, START_TIME, END_TIME
REAL TIME, W(8192, 21, 3, 6, 100)
W=1.0
CALL SYSTEM_CLOCK(COUNT_RATE = RATE)
MAX_X = 3
MAX_Y = 4
MAX_Z = 5
WRITE (*, *) 'Writing input files'
CALL SYSTEM_CLOCK(START_TIME)
OPEN (100, FORM = 'unformatted', FILE = 'file.dat')
DO X = 1, MAX_X
DO Y = 1, MAX_Y
DO Z = 1, MAX_Z
ISOUR = (X - 1) * MAX_Y * MAX_Z + (Y - 1) * MAX_Z + Z
DO IR = 1, 6
DO IT = 1, 6
DO ITIM = 1, 8192
TIME=REAL(ITIM)
WRITE (100) TIME, W(ITIM, IR, 1, IT, ISOUR), W(ITIM, IR, 2, IT, ISOUR), W(ITIM, IR, 3, IT, ISOUR)
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
CLOSE (100)
CALL SYSTEM_CLOCK(END_TIME)
WRITE (*, *) 'Write time required: ', REAL(END_TIME - START_TIME)/REAL(RATE)
WRITE (*, *) 'Reading input files'
CALL SYSTEM_CLOCK(START_TIME)
OPEN (100, FORM = 'unformatted', FILE = 'file.dat')
DO X = 1, MAX_X
DO Y = 1, MAX_Y
DO Z = 1, MAX_Z
ISOUR = (X - 1) * MAX_Y * MAX_Z + (Y - 1) * MAX_Z + Z
DO IR = 1, 6
DO IT = 1, 6
DO ITIM = 1, 8192
READ (100) TIME, W(ITIM, IR, 1, IT, ISOUR), W(ITIM, IR, 2, IT, ISOUR), W(ITIM, IR, 3, IT, ISOUR)
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
CLOSE (100)
CALL SYSTEM_CLOCK(END_TIME)
WRITE (*, *) 'Read time required: ', REAL(END_TIME - START_TIME)/REAL(RATE)
END PROGRAM TEST_INPUT