On Mon, Nov 20, 2017 at 12:56 AM, Jerry DeLisle <jvdeli...@charter.net> wrote: > Hi all, > > After the usual considerable digging around I determined that for the test > case > doing 1000000 writes to a string that we were allocating 1000000 newunit > numbers > and the associated unit structures on the unit treap. Consequently, at the end > of the program, when all left open units are cleaned up and closed, a lot of > time was being burned. We did not benefit from the previously allocated unit > structures saved on the treap that could be reused. > > IO operations on strings complete with st_read_done or st_write_done of the > parent IO procedure. To fix the problem, I simply declared newunit_alloc > accessible to transfer.c and invoked it. > > Now unit numbers and their associated unit structures are reused as they > should > be and internal unit I/O is just a little bit better than on gfortran version > 6. > > My test results with the test case in the PR are as follows. (I commented out > the intermediate write to stdout for clarity) > > Patched trunk: > > $ gfc -static pr78549.f > $ time ./a.out > > real 0m22.476s > user 0m22.183s > sys 0m0.180s > > And gfortran 6: > > $ gfc6 -static pr78549.f > $ time ./a.out > > real 0m22.790s > user 0m22.633s > sys 0m0.011s > > Unpatched gfortran 7: > > $ gfc7 -static pr78549.f > $ time ./a.out > > real 0m29.915s > user 0m28.750s > sys 0m0.971s > > > Regression tested on x86-64-linux. > > I will commit to trunk in a day and back port to 7 in a few more days if no > objections. The patch is simple. > > Regards, > > Jerry > > 2017-11-19 Jerry DeLisle <jvdeli...@gcc.gnu.org> > > PR libgfortran/78549 > * io/io.h (newunit_free): Add declaration. Clean some whitespace. > * io/transfer.c (st_read_done, st_write_done): Call newunit_free. > * io/unit.c (newunit_free): Change type from static void to void.
In the patch: extern void finish_last_advance_record (gfc_unit *u); -internal_proto (finish_last_advance_record); +internal_proto(finish_last_advance_record); extern int unit_truncate (gfc_unit *, gfc_offset, st_parameter_common *); -internal_proto (unit_truncate); +internal_proto(unit_truncate); extern int newunit_alloc (void); internal_proto(newunit_alloc); +extern void newunit_free (int); +internal_proto (newunit_free); + Since you're fixing the whitespace for finish_last_advance_record and unit_truncate, you might as well do it right for newunit_free from the start.. :) Otherwise Ok, thanks for the patch! -- Janne Blomqvist