Performance-Aware Loops
Loop Order Shape
Match the Array Layout
Fortran arrays are column-major, so loop order is part of performance-aware design even when no elapsed-time measurement is run.
Program
Play the program to choose a traversal shape and see the same grid summarized with different visit patterns.
loop_order_shape.f90
program loop_order_shape_demo
implicit none
integer :: grid(2, 3)
integer :: order_mode
integer :: row
integer :: col
integer :: visits
integer :: total
character(len=12) :: order_name
grid = reshape([1, 2, 3, 4, 5, 6], [2, 3])
order_mode =
visits = 0
total = 0
if (order_mode == 1) then
order_name = 'column'
do col = 1, 3
do row = 1, 2
visits = visits + 1
total = total + grid(row, col)
end do
end do
else if (order_mode == 2) then
order_name = 'row'
do row = 1, 2
do col = 1, 3
visits = visits + 1
total = total + grid(row, col)
end do
end do
else
order_name = 'sample'
do col = 1, 3
row = 1 + mod(col + 1, 2)
visits = visits + 1
total = total + grid(row, col)
end do
end if
print '(A, 1X, I0, 1X, I0)', trim(order_name), visits, total
end program loop_order_shape_demo
program loop_order_shape_demo
implicit none
integer :: grid(2, 3)
integer :: order_mode
integer :: row
integer :: col
integer :: visits
integer :: total
character(len=12) :: order_name
grid = reshape([1, 2, 3, 4, 5, 6], [2, 3])
order_mode =
visits = 0
total = 0
if (order_mode == 1) then
order_name = 'column'
do col = 1, 3
do row = 1, 2
visits = visits + 1
total = total + grid(row, col)
end do
end do
else if (order_mode == 2) then
order_name = 'row'
do row = 1, 2
do col = 1, 3
visits = visits + 1
total = total + grid(row, col)
end do
end do
else
order_name = 'sample'
do col = 1, 3
row = 1 + mod(col + 1, 2)
visits = visits + 1
total = total + grid(row, col)
end do
end if
print '(A, 1X, I0, 1X, I0)', trim(order_name), visits, total
end program loop_order_shape_demo
program loop_order_shape_demo
implicit none
integer :: grid(2, 3)
integer :: order_mode
integer :: row
integer :: col
integer :: visits
integer :: total
character(len=12) :: order_name
grid = reshape([1, 2, 3, 4, 5, 6], [2, 3])
order_mode =
visits = 0
total = 0
if (order_mode == 1) then
order_name = 'column'
do col = 1, 3
do row = 1, 2
visits = visits + 1
total = total + grid(row, col)
end do
end do
else if (order_mode == 2) then
order_name = 'row'
do row = 1, 2
do col = 1, 3
visits = visits + 1
total = total + grid(row, col)
end do
end do
else
order_name = 'sample'
do col = 1, 3
row = 1 + mod(col + 1, 2)
visits = visits + 1
total = total + grid(row, col)
end do
end if
print '(A, 1X, I0, 1X, I0)', trim(order_name), visits, total
end program loop_order_shape_demo
column-major
Fortran stores the leftmost subscript contiguously.
loop order
Changing traversal order changes the access pattern, not the mathematical total.
shape summary
A small visit count and total can explain the loop shape without timing.