Fortran performance when passing array slices as arguments

I like fortran array-slicing notation ( array(1:n) ), but I am wondering if I can get a performance hit if I use them when it is not needed.

Consider, for example, this simple quick-sort code (it works, but it is obvious that it does not care about choosing a good core):

 recursive subroutine quicksort(array, size) real, dimension(:), intent(inout) :: array integer, intent(in) :: size integer :: p if (size > 1) then p = partition(array, size, 1) call quicksort(array(1:p-1), p-1) call quicksort(array(p+1:size), size-p) end if end subroutine quicksort function partition(array, size, pivotdex) result(p) real, dimension(:), intent(inout) :: array integer, intent(in) :: size, pivotdex real :: pivot integer :: i, p pivot = array(pivotdex) call swap(array(pivotdex), array(size)) p=1 do i=1,size-1 if (array(i) < pivot) then call swap(array(i), array(p)) p=p+1 end if end do call swap(array(p), array(size)) end function partition subroutine swap(a, b) real, intent(inout) :: a, b real :: temp temp = a a = b b = temp end subroutine swap 

I could just pass the whole array along with the indices in which the recursive parts should work, but I like the code this way. However, when I call quicksort(array(1:p-1), p-1) , does it make it a temporary array, or does it just create a shallow link structure or something like that? Is this a reasonably effective solution?

This question is related, but it looks like it creates temporary arrays due to alternating fragments and explicit dimensional variables, so I'm safe from this, right?

0
fortran slice fortran90
source share
2 answers

Your submanipulator

  array(1:p-1) 

is continuous if array contiguous.

In addition, you use the argument argument of the intended argument of the form

  real, dimension(:), intent(inout) :: array 

No need for temporary. A handle to the alleged form array has been passed. And since your subarray is contiguous, even the intended size, the explicit size, or the estimated dimensional dummy argument with the contiguous attribute will be fine.

+2
source share

As for your efficiency question: Yes, for most cases, using arrays of the intended forms and arrays of arrays is indeed a fairly effective solution.

There is some overhead. Arrays with the intended shape require an array descriptor (sometimes also called a "doping vector"). This array descriptor contains information about sizes and steps, and setting it up requires some work.

The code in the called procedure with the argument of the dummy argument should take both a single step (the usual case) and an odd step. Someone might want to call your sort procedure with the actual argument somearray (1: 100: 3), because he only wants to sort every third element of the array. Unusual, but legal. Code that cannot depend on a unity step may have some performance limitation.

Having said that, compilers, especially those who use connection time optimization, are currently good at integrating and / or discarding all additional work, and are also inclined to clone procedures for individual unity steps.

So, as a rule, clarity (and arrays of the supposed form) should prevail. Just keep in mind that the old-fashioned way of passing array arguments can in some cases get extra efficiency.

+2
source share

All Articles