This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR 56981 Improve unbuffered unformatted performance


Hi,

the attached patch improves the performance for unformatted and
unbuffered files. Currently unbuffered unformatted really means that
we don't buffer anything and use the POSIX I/O syscalls directly. With
the patch, we use the buffer but flush it at the end of each I/O
statement.

(For formatted I/O we essentially already do this, as the format
buffer (fbuf) buffers each record).

For the ever important benchmark of writing small (containing a single
scalar 4 byte value) unformatted sequential records to /dev/null, the
patch reduces the number of syscalls by a factor of 6, and performance
improves by more than double.

For trunk, time for the benchmark in the PR:

real    0m0.727s
user    0m0.272s
sys     0m0.452s

With the patch:

real    0m0.313s
user    0m0.220s
sys     0m0.092s

For comparison, writing to a file where we use buffered I/O:

real    0m0.202s
user    0m0.180s
sys     0m0.020s


As a semi-unrelated minor improvement, the patch also changes the
ordering when writing out unformatted sequential record markers.
Currently we do

write bogus marker
write record data
write tail marker
seek back to before the bogus marker
write the correct head marker
seek to the end of the record, behind the tail marker

With the patch we instead do

write bogus marker
write record data
seek back to before the bogus marker
write the correct head marker
seek to the end of the record data
write tail marker

With the patch, the slightly shorter seek distances ever-so-slightly
increase the chance that the seeks will be contained within the buffer
so we don't have to flush.

Regtested on x86_64-unknown-linux-gnu, Ok for trunk?

2013-04-19  Janne Blomqvist  <jb@gcc.gnu.org>

    PR fortran/56981
    * io/transfer.c (next_record_w_unf): First fix head marker, then
    write tail.
    (next_record): Call flush_if_unbuffered.
    * io/unix.c (struct unix_stream): Add field unbuffered.
    (flush_if_unbuffered): New function.
    (fd_to_stream): New argument.
    (open_external): Fix fd_to_stream call.
    (input_stream): Likewise.
    (output_stream): Likewise.
    (error_stream): Likewise.
    * io/unix.h (flush_if_unbuffered): New prototype.


--
Janne Blomqvist

Attachment: unfunbuf.diff
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]