6

To initialize and assign value to arrays in Fortran we do as the following:

Initializing:

real(kind=8):: r(3,4)
...
r(:,:) = 0.0_8

what if we use only

real(kind=8):: r(3,4)
...
r = 0.0_8

and what if we do as:

real(kind=8):: r(3,4)
...
r = 0

also for situation such as:

real(kind=8):: r(3,4), q(3,4), p(30,40)
...
q = 0
r = q
r = p(1:3,21:24)

we prefer to do as:

real(kind=8):: r(3,4), q(3,4), p(30,40)
...
q = 0.0_8
r(:,:) = q(:,:)
r(:,:) = p(1:3,21:24)

we are not sure so hope you provide us some reasons for each one you prefer.

2 Answers 2

13

For general considerations (including declaration and assignation) about efficiently using arrays in Fortran, I would suggest to read this.

For more precise answer to your question, I did some tests some months ago that may interest you. Here are the results. This is a test on my personnal laptop on Linux Archlinux x86-64, with GNU Fortran (GCC) 4.6.1 20110819 (prerelease) without optimization options.

do i = 1 , 100
  do j = 1 , 100
    do k = 1 , 100 ! innest is fastest
      array ( i , j , k ) = 0.0d0
    end do
  end do
end do
! reference time : 1.00

to

do i = 1 , 100
  do j = 1 , 100
    do k = 1 , 100
      array ( k , j , i ) = 0.0d0
    end do
  end do
end do
! time : 0.499

to

array = 0.0d0
! time : 0.250

to

array ( : , : , : ) = 0.0d0
! time : 0.250
Sign up to request clarification or add additional context in comments.

2 Comments

Hi Max, the link to your work is broken. Moreover, I'm not sure what a comparison with optimization turned off would reveal. The inner loop here would optimize trivially. Often your examples 2,3,4 will be the same in optimized mode.
I guess the time difference is due to the way array is stored in memory. In Fortran, take 2 dimensional matrix for example, column vectors are stored continuously instead of row vectors which is the case of C++.
6

Do you think that "kind=8" means 8 bytes? That isn't true for all compilers. The maximum portability is achieved using the selected_real_kind intrinsic to define a kind value:

integer, parameter :: DRK = selected_real_kind (14)

Of some of the options that you list, I prefer r = 0.0_8, or better r=0.0_DRK. This defines the entire array. There is no need to designate array sections in this case, since you are calling out the entire array: r (:, :). Steve Lionel has a discussion of why trying to make arrays obvious with ":" isn't a good idea -- there are differences between array and array (:). As an argument, the first has it declared dimensions, while the second always begins at 1 -- see http://software.intel.com/en-us/blogs/2008/03/31/doctor-it-hurts-when-i-do-this/

Since r is real, r=0 implies a conversion. For the value zero this almost certainly doesn't matter, but it could make an important difference with other values. e.g.,

r = 3.1415927654

and

r = 3.141592654_8

will give different values to r because the constants are different, the first being converted to single precision before the assignment.

1 Comment

The part about kind=8 not being equivalent to 8 bytes has been discussed a lot in the past. It is somewhat of a general opinion that kind types should't have been designated with integers to begin with. It causes a lot of confusion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.