[patch, libfortran] [4.7/4.8/4.9 Regression] PR38199 missed optimization: I/O performance
Jerry DeLisle
jvdelisle@charter.net
Sun Mar 9 00:55:00 GMT 2014
On 03/08/2014 02:37 PM, Manfred Schwarb wrote:
---snip---
>
> This is great.
>
> However, this is still 10 times slower than the LEN_TRIM variant:
> character buffer(1)*100000
> integer i,j
>
> j = 1234
> write(buffer(1),'(i4)') j
>
> DO j=1,9999
> ! write(*,*) buffer(1)(1:4)
> read(buffer(1)(1:LEN_TRIM(buffer(1))),*) i
> ! write(*,*) i
> ENDDO
> end
>
Lets clarify some things. We have two different test cases here
case 1: read(buffer(1:LEN_TRIM(buffer(1))),*) i
Before patch:
real 0m24.286s
user 0m24.172s
sys 0m0.013s
After patch:
real 0m2.847s
user 0m2.835s
sys 0m0.000s
case 2: read(buffer(1)(1:LEN_TRIM(buffer(1))),*) i
Before patch:
real 0m0.233s
user 0m0.229s
sys 0m0.002s
After patch
real 0m0.231s
user 0m0.229s
sys 0m0.000s
case 1 is treated as a character array unit and -fdump-tree-original gives:
D.2323 = (integer(kind=8)) _gfortran_string_len_trim (100000, &buffer[0]);
parm.2.dtype = 6400049;
parm.2.dim[0].lbound = 1;
parm.2.dim[0].ubound = D.2323;
parm.2.dim[0].stride = 1;
parm.2.data = (void *) &buffer[0];
parm.2.offset = -1;
dt_parm.1.internal_unit = (character(kind=1) *) parm.2.data;
dt_parm.1.internal_unit_len = 100000;
dt_parm.1.internal_unit_desc = (character(kind=1) *) &parm.2;
dt_parm.1.common.unit = 0;
dt_parm.1.common.flags = 16512;
_gfortran_st_read (&dt_parm.1);
_gfortran_transfer_integer (&dt_parm.1, &i, 4);
_gfortran_st_read_done (&dt_parm.1);
case 2 is treated as a scalar unit and -fdump-tree-original gives:
D.2323 = _gfortran_string_len_trim (100000, &buffer[0]);
dt_parm.1.internal_unit = (character(kind=1) *) &buffer[0];
dt_parm.1.internal_unit_len = MAX_EXPR <NON_LVALUE_EXPR <D.2323>, 0>;
dt_parm.1.internal_unit_desc = 0B;
dt_parm.1.common.unit = 0;
dt_parm.1.common.flags = 16512;
_gfortran_st_read (&dt_parm.1);
_gfortran_transfer_integer (&dt_parm.1, &i, 4);
_gfortran_st_read_done (&dt_parm.1);
Both cases are compiling in the LEN_TRIM. The slow case has to deal with the
array descriptor and looping through from lbound to ubound. We probably could
do some additional front end magic, but for now I will commit the runtime patch
Regards,
Jerry
More information about the Fortran
mailing list