Print

Print


I have a problem similar to Naomi's, in that I have a procedure that is
executed numerous times with different amounts of data.

Here's how I solve it, rather than trying to outwit the compiler's
memory allocator.

The first stage is to calculate the maximum dimensions of the several
(seventy or so) arrays.  Fortunately this only requires fewer than a
dozen numbers.

Then I call another subroutine that has all of the arrays automatic with
their maximum sizes.  This is primarily to avoid seventy or so allocate
and deallocate statements, and associated status checking, although
there is some hope that a processor might handle all the automatic
variables in a procedure more efficiently than separate explicit
allocations of each of them.  That is, doing "under the covers" what
Naomi is trying to do explicitly.

Within this subroutine, I call yet other subroutines, passing the parts
of the arrays appropriate to the particular invocation as actual
arguments.  E.g.,

  call opacity ( ct(1:npc), stcp(1:npc), stsp(1:npc), &
    & alpha_path_polarized(:,1:npc), incoptdepth_pol(:,:,1:npc) )


Within those subroutines the arrays have assumed shape, so whole-array
operations apply to just the parts relevant to each subproblem.  E.g.,
  subroutine Opacity ( CT, STCP, STSP, Alpha_path, Del_opcty )
    real(rk), intent(in) ::    CT(:)     ! Cos(Theta)
    real(rk), intent(in) ::    STCP(:)   ! Sin(Theta) Cos(Phi)
    real(rk), intent(in) ::    STSP(:)   ! Sin(Theta) Sin(Phi)
    complex(rk), intent(in) ::  Alpha_path(-1:,:) ! (-1:1,:)
    complex(rk), intent(out) :: Del_opcty(:,:,:)  ! (2,2,:)

When the CONTIGUOUS attribute is available in all the compilers I use,
I'll add it to the dummy argument declarations.  I have tried
assumed-size in many of the low-level procedures, and it only made a
difference in one of them.  Interestingly, the effect was the opposite
on two different compilers.  Presumably they both benefited from the
assumption of contiguity in the called procedure, but one of them
decided it needed to make a copy of the actual argument, without
bothering to check that the actual argument was contiguous, and the
overall runtime increased.

On Thu, 2010-06-24 at 12:42 -0700, Greenberg, Naomi wrote:
> I'll try to clarify with an example. What I want to do is replace:
>    Real, allocatable :: array1(:), array2(:), array(3)
>    Allocate (array1(7000))
>    Allocate (array2(444))
>    ...
>    Deallocate (array1)
>    Allocate (array1(33333))
>   Etc. with something like
>   Initialize up front, once: allocate Memory(100000)
> 
>    Real, allocatable :: array1(:), array2(:), array(3)
>    Call allocMemMgr ( 7000, array1 )
>    Call allocMemMgr ( 444, array2 )
>   Etc. and have array1(100) be addressable in the main program.  The only thing I can think of is having the manager return a start location and having the user of this manager explicitly use Memory(startLoc:startLoc+size) instead of an array.
> 
>    Even were I to use equivalence, I'd have to declare each array a fixed size before equivalencing it to Memory(startLoc), wouldn't I?  And this size changes during the program.  So equivalence won't work.  I'm no expert on pointers, but I thought they were dynamically allocated as well, which would defeat my purpose. This application will be running for many days and will be dividing a huge matrix into pieces of varying sizes, doing operations on them, and then moving on to process other pieces of the matrix.
> 
> Thanks,
> Naomi
> 
> -----Original Message-----
> From: Fortran 90 List [mailto:[log in to unmask]] On Behalf Of Peter Shenkin
> Sent: Thursday, June 24, 2010 3:22 PM
> To: [log in to unmask]
> Subject: Re: Memory management question
> 
> On Thu, Jun 24, 2010 at 2:49 PM, Ted Stern <[log in to unmask]> wrote:
> > On 24 Jun 2010 11:40:59 -0700, Vivek Rao wrote:
> >>
> >> Hello.
> >>
> >> If x(:) is your big array, in Fortran 90+ you can define a pointers x1(:), x2
> >> (:) etc. that refer to sections of it, for example
> >>
> >> allocate (x(1000000)
> >> x1 => x(1:300000)
> >> x2 => x(300001:1000000)
> >>
> >> Vivek Rao
> >
> > Naomi was specifically asking how to avoid slowdowns due to use of
> > pointers.
> 
> Not the way I read her email.
> 
> I thought she was asking how to avoid slowdowns due to dynamic allocation.
> 
> But I have to say that I've never met anyone who tried to outwit the
> system's dynamic allocator who came to a good end. The system Naomi is
> suggesting is what we had to do in the bad old days, when we'd malloc
> a huge array in C and find some kludgy way to equivalence Fortran
> arrays to it.
> 
> -P.
> 
> 
> __________ Information from ESET NOD32 Antivirus, version of virus signature database 5226 (20100624) __________
> 
> The message was checked by ESET NOD32 Antivirus.
> 
> http://www.eset.com
> 
> 
> 
> __________ Information from ESET NOD32 Antivirus, version of virus signature database 5226 (20100624) __________
> 
> The message was checked by ESET NOD32 Antivirus.
> 
> http://www.eset.com