Performance-Aware Loops
Counted Work
Bound the Loop
Performance-aware code starts by making the amount of loop work explicit, before any timing or tuning claims.
Program
Play the program to choose how many values are included and watch the operation count stay visible.
counted_work.f90
Replay: real traced execution (multi-file project)
program counted_work_demo
implicit none
integer :: values(5)
integer :: limit
integer :: i
integer :: total
integer :: operations
values = [2, 4, 6, 8, 10]
limit = 3
total = 0
operations = 0
do i = 1, limit
total = total + values(i)
operations = operations + 1
end do
print '(I0, 1X, I0)', total, operations
end program counted_work_demo
program counted_work_demo
implicit none
integer :: values(5)
integer :: limit
integer :: i
integer :: total
integer :: operations
values = [2, 4, 6, 8, 10]
limit = 2
total = 0
operations = 0
do i = 1, limit
total = total + values(i)
operations = operations + 1
end do
print '(I0, 1X, I0)', total, operations
end program counted_work_demo
program counted_work_demo
implicit none
integer :: values(5)
integer :: limit
integer :: i
integer :: total
integer :: operations
values = [2, 4, 6, 8, 10]
limit = 5
total = 0
operations = 0
do i = 1, limit
total = total + values(i)
operations = operations + 1
end do
print '(I0, 1X, I0)', total, operations
end program counted_work_demo
values ← [2, 4, 6, 8, 10]
9values = [2, 4, 6, 8, 10]10limit = 3values this step[2, 4, 6, 8, 10]valueslimit ← 3
9values = [2, 4, 6, 8, 10]10limit = 311total = 0values this step3limittotal ← 0
10limit = 311total = 012operations = 0values this step0totaloperations ← 0
11total = 012operations = 013do i = 1, limitvalues this step0operationstotal ← 2
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step0 → 2total1i2values(i)operations ← 1
14 total = total + values(i)15 operations = operations + 116end dovalues this step0 → 1operationstotal ← 6
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step2 → 6total2i4values(i)operations ← 2
14 total = total + values(i)15 operations = operations + 116end dovalues this step1 → 2operationstotal ← 12
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step6 → 12total3i6values(i)operations ← 3
14 total = total + values(i)15 operations = operations + 116end dovalues this step2 → 3operationsprint '(I0, 1X, I0)', total, operations
16 end do17 print '(I0, 1X, I0)', total, operations18end program counted_work_demooutput12 3values this step12total3operations
values ← [2, 4, 6, 8, 10]
9values = [2, 4, 6, 8, 10]10limit = 2values this step[2, 4, 6, 8, 10]valueslimit ← 2
9values = [2, 4, 6, 8, 10]10limit = 211total = 0values this step2limittotal ← 0
10limit = 211total = 012operations = 0values this step0totaloperations ← 0
11total = 012operations = 013do i = 1, limitvalues this step0operationstotal ← 2
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step0 → 2total1i2values(i)operations ← 1
14 total = total + values(i)15 operations = operations + 116end dovalues this step0 → 1operationstotal ← 6
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step2 → 6total2i4values(i)operations ← 2
14 total = total + values(i)15 operations = operations + 116end dovalues this step1 → 2operationsprint '(I0, 1X, I0)', total, operations
16 end do17 print '(I0, 1X, I0)', total, operations18end program counted_work_demooutput6 2values this step6total2operations
values ← [2, 4, 6, 8, 10]
9values = [2, 4, 6, 8, 10]10limit = 5values this step[2, 4, 6, 8, 10]valueslimit ← 5
9values = [2, 4, 6, 8, 10]10limit = 511total = 0values this step5limittotal ← 0
10limit = 511total = 012operations = 0values this step0totaloperations ← 0
11total = 012operations = 013do i = 1, limitvalues this step0operationstotal ← 2
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step0 → 2total1i2values(i)operations ← 1
14 total = total + values(i)15 operations = operations + 116end dovalues this step0 → 1operationstotal ← 6
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step2 → 6total2i4values(i)operations ← 2
14 total = total + values(i)15 operations = operations + 116end dovalues this step1 → 2operationstotal ← 12
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step6 → 12total3i6values(i)operations ← 3
14 total = total + values(i)15 operations = operations + 116end dovalues this step2 → 3operationstotal ← 20
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step12 → 20total4i8values(i)operations ← 4
14 total = total + values(i)15 operations = operations + 116end dovalues this step3 → 4operationstotal ← 30
13do i = 1, limit14 total = total + values(i)15 operations = operations + 1values this step20 → 30total5i10values(i)operations ← 5
14 total = total + values(i)15 operations = operations + 116end dovalues this step4 → 5operationsprint '(I0, 1X, I0)', total, operations
16 end do17 print '(I0, 1X, I0)', total, operations18end program counted_work_demooutput30 5values this step30total5operations
work bound
`limit` makes the loop bound visible and easy to reason about.
operation count
`operations` records how many iterations actually ran.
work shape
Counting work shows the performance shape without measuring elapsed time.