[patch, libgfortran] [4.8/4.9/5 Regression] error reading (and writing) large text files in gfortran
Jerry DeLisle
jvdelisle@charter.net
Sat Feb 7 02:08:00 GMT 2015
With the attached patch I create a special version of fbuf_flush that is only
called with list directed I/O. There can be no tabbing back and forth so it is
safe to flush the buffer whenever we want. The bug occurs when the buffer keeps
growing to no end until no more allocations can be made and the OS gives an error.
fbuf_flush can be called as much as one wants to, but to keep overhead low, I
introduce a new version with an arbitrary limit. If below the limit, just
return doing no flushing. When the limit is exceeded, fbuf is flushed. The
code to do this is duplicated from the original fbuf_flush so it is very safe
and well tested.
I played with the allowable maximum position limit for flushing and ran some
timing tests. My machine here uses a solid state drive which may bias the
results somewhat. Others are welcome to test and see what values they get as
well. I settled on 524588 based on these results, favoring writing over reading
a little.
The patch has zero impact on any other type of I/O including normal formatted
I/O. I also tested to confirm that formatted I/O does not have the problem. It
is flushed regularly in the main transfer loop. As far as I can tell only list
directed has the issue.
I get the following timings using the attached test program.
WRITING:
Array Size--> 1000000 100000000
Buf Limit
16384 2.107 210.9
32768 2.026 292.1
65636 2.232 235.8
524288 1.958 193.5
1048576 2.023 203.5
READING:
Buf Limit
16384 1.843 184.4
32768 1.841 186.8
65636 1.816 197.6
524288 1.879 186.5
1048576 1.834 185.2
Regression tested on x86-64 Linux.
OK for trunk followed by backports?
I can not include a specific testsuite test case, it would take way too long to run.
Regards,
Jerry
2015-02-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/60956
* io/fbuf.c (fbuf_flush_list): New function that only flushes
if current fbuf position exceeds a limit.
* io/fbuf.h: Declare the new function.
* io/io.h (enum unit_mode): Add two new modes.
* io/list_read.c (list_formatted_read_scalar): Call new function.
* io/write.c: Include fbuf.h. (list_formatted_write_scalar):
Call new function.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr60956.diff
Type: text/x-patch
Size: 2792 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150207/4e5df304/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_complex_io.f90
Type: text/x-fortran
Size: 1024 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150207/4e5df304/attachment-0001.bin>
More information about the Gcc-patches
mailing list