When manipulating and assigning subarrays to multidimensional arrays in Fortran90, I came across an interesting performance feature.
Fortran90 introduced the ability to manipulate subsections of arrays, and I saw several places that recommend performing array operations using this โclippingโ method instead of loops. For example, if I need to add two arrays, aand with a bsize of 10, it is better to write:
c(1:10) = a(1:10) + b(1:10)
or
c = a + b
Instead
do i = 1, 10
c(i) = a(i) + b(i)
end do
I tried this method for simple one-dimensional and two-dimensional arrays and found that it is faster with "slice" notation. However, when assigning such results in multidimensional arrays, it became a little more interesting.
, . , , , , .
program main
implicit none
integer, parameter :: mSize = 10000
integer :: i, j
integer :: pCnt, nCnt, cntRt, cntMx
integer, dimension(mSize, mSize) :: a, b
integer, dimension(mSize, mSize, 3) :: c
pCnt = 0
call SYSTEM_CLOCK(nCnt, cntRt, cntMx)
print *, "First call: ", nCnt-pCnt
pCnt = nCnt
do j = 1, mSize
do i = 1, mSize
a(i, j) = i*j
b(i, j) = i+j
end do
end do
call SYSTEM_CLOCK(nCnt, cntRt, cntMx)
print *, "Created Matrices: ", nCnt-pCnt
pCnt = nCnt
do j = 1, mSize
do i = 1, mSize
c(i, j, 1) = a(i, j) + b(i, j)
c(i, j, 2) = a(i, j) - b(i, j)
c(i, j, 3) = a(i, j) * b(i, j)
end do
end do
call SYSTEM_CLOCK(nCnt, cntRt, cntMx)
print *, "Added Matrices: ", nCnt-pCnt
pCnt = nCnt
end program main
, 2D- 3D-. , . , , , .
-O3 GNU Fortran 4.8.4 Ubuntu 14.04
-O3
.
5 Runs - 843, 842, 842, 841, 859
Average - 845.4
.
5 Runs - 1713, 1713, 1723, 1711, 1713
Average - 1714.6
-O3
.
5 Runs - 545, 545, 544, 544, 548
Average - 545.2
.
5 Runs - 479, 477, 475, 472, 472
Average - 475
, -O3 , . -O3 . , .
, 3D , . , . ?
, , OO . ? - , ? . !