Fortran Multidimensional Array Performance

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

    ! OPERATIONS BY SLICING NOTATION
    !c(1:mSize, 1:mSize, 1) = a + b
    !c(1:mSize, 1:mSize, 2) = a - b
    !c(1:mSize, 1:mSize, 3) = a * b

    ! OPERATIONS WITH LOOP
    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 . ? - , ? . !

+4
2

. , . , .

, , . 3 , haraldkl, .

, 3 , , 3 . a b , a b 3 . . , , .

+4

, , , ... , :

do j = 1, mSize
    do i = 1, mSize
        c(i, j, 1) = a(i, j) + b(i, j)
    end do
end do
do j = 1, mSize
    do i = 1, mSize
        c(i, j, 2) = a(i, j) - b(i, j)
    end do
end do
do j = 1, mSize
    do i = 1, mSize
        c(i, j, 3) = a(i, j) * b(i, j)
    end do
end do

, , , , , - c .

+2

Source: https://habr.com/ru/post/1605826/


All Articles