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]

Re: [patch,libgfortran] PR48298 DTIO implementation for Internal Units


Hi Jerry,

Am 14.09.2016 um 07:56 schrieb Jerry DeLisle:
> Hi All,
> 
> The attached patch implements the necessary changes for DTIO to/from internal units.
> 
> Prior to this patch, internal unit character strings and related data were kept within the dtp structure with a pseudo unit number assigned. Since child I/O procedures need this information passed to them through the unit number, it is necessary to move this information into the gfc_unit structure.
> 
> This also implies that the internal unit needs a legitimate and unique unit number. This is accomplished using the existing newunit mechanisms to obtain a unit number and then allocating the unit structure on the existing treap mechanism used for all units.  The child I/O procedures can then find the units for use.
> 

How does this affect performance?
I mean, reading and writing to/from internal units is a common thing and is 
certainly performance critical in some cases. It is already slow as is,
so it would be sad to slow down this mechanism even further.
Does acquiring a new unit and allocating the structure impair performance?
Or does your stack approach mitigate this completely?

Thanks,
Manfred



> The existing method of getting a newunit number simply decrements an integer which then contains the next available number.  One problem with this is that with internal units used inside a loop, each call will get the next number and one will end up with hundreds or many thousands of units.
> 
> To work around this I implemented a stack to save unit numbers. After the internal unit I/O is completed, the unit structure is left on the treap and the unit number is saved on the stack, The next time an internal unit number is needed, it will be popped off this stack and used.  Since the associated unit structure remains on the treap, it is found and reused, without having to reallocate memory for it.
> 
> Once all these changes are made to the handling of internal units, the existing DTIO just works as usual.
> 
> Regression tested on x86-64 linux. New test case attached.
> 
> OK for trunk?
> 
> Regards,
> 
> Jerry
> 
> 2016-09-14  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
> 
>     PR fortran/48298
>     * io.c (gfc_match_inquire): Adjust error message for internal
>     unit KIND.
>     * libgfortran.h: Adjust defines for GFC_INTERNAL_UNIT4,
>     GFC_INTERNAL_UNIT, and GFC_INVALID_UNIT.
>     * trans-io.c (build_dt): Set common_unit to reflect the KIND of
>     the internal unit.
> 
> 2016-09-14  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
> 
>     PR fortran/48298
>     * io/inquire.c (inquire_via_unit): Adjust error check for the
>     two possible internal unit KINDs.
>     * io/io.h: Adjust defines for is_internal_unit and
>     is_char4_unit. (gfc_unit): Add internal unit data to structure.
>     (get_internal_unit): Change declaration to set_internal_unit.
>     (free_internal_unit): Change name to stash_internal_unit_number.
>     (get_unique_unit_number): Adjust parameter argument.
>     * io/list_read.c (next_char_internal): Use is_char4_unit.
>     * io/open.c (st_open): Adjust call to get_unique_unit_number.
>     * io/transfer.c (write_block): Use is_char4_unit.
>     (data_transfer_init): Update check for unit numbers.
>     (st_read_done): Free the various allocated memories used for the
>     internal units and stash the negative unit number to allow
>     reuse. (st_write_done): Likewise stash the freed unit number.
>     * io/unit.c: Create a fixed size buffer of 256 integers to use
>     as a stack to save newunit unit numbers for later reuse.
>     (get_external_unit): Change name to get_gfc_unit to better
>     reflect what it does. (find_unit): Change call to get_gfc_unit.
>     (find_or_create_unit): Likewise. (get_internal_unit): Change
>     name to set_internal_unit. Move internal unit from the dtp
>     structure to the gfc_unit structure so that it can be passed to
>     child I/O statements through the UNIT.
>     (free_internal_unit): Change name to stash_internal_unit_number.
>     Push the common.unit number onto the newunit stack, saving it
>     for possible reuse later. (get_unit): Set the internal unit
>     KIND. Use get_unique_unit_number to get a negative unit number
>     for the internal unit. Use get_gfc_unit to get the unit structure
>     and use set_internal_unit to initialize it.
>     (init_units): Initialize the newunit stack.
>     (get_unique_unit_number): Check the stack for an available unit
>     number and use it. If none there get the next most negative
>     number.


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