---
jupytext:
formats: md:myst
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: Python 3
language: python
name: python3
---Section: Implicit vs. Explicit Loops¶
This program demonstrates the speed of implicit vs. explicit loops in Fortran.¶
The program will take in a command line argument and construct two argument X argument sized matrices composed of random numbers. The program will then compute the following:
where:
is the summation result
and are command line argument X command line argument sized matrices
program real32_vs_real64
use, intrinsic :: iso_fortran_env, only : error_unit, I8 => INT64, &
SP => REAL32, DP => REAL64
implicit none
integer(kind=I8) :: nr_values
real(kind=SP), dimension(:), allocatable :: x_sp, y_sp
real(kind=SP) :: result
real :: start_time, end_time
integer :: status, i
call get_argument(nr_values)
! implicit loops
allocate (x_sp(nr_values), y_sp(nr_values), stat=status)
if (status /= 0) then
write (unit=error_unit, fmt='(A)') 'error: can not allocate x_sp/y_sp'
stop 1
end if
call random_number(x_sp)
call random_number(y_sp)
call cpu_time(start_time)
result = sum(sqrt(x_sp**2 + y_sp**2))
call cpu_time(end_time)
print '(A, F20.8)', 'Implicit loop time [s]: ', end_time - start_time
print '(A, F20.8)', 'Summation result: ', result
deallocate (x_sp, y_sp)
! explicit loops
allocate (x_sp(nr_values), y_sp(nr_values), stat=status)
if (status /= 0) then
write (unit=error_unit, fmt='(A)') 'error: can not allocate x_sp/y_sp'
stop 1
end if
call random_number(x_sp)
call random_number(y_sp)
call cpu_time(start_time)
result = 0.0_SP
do i = 1, size(x_sp)
result = result + sqrt(x_sp(i)**2 + y_sp(i)**2)
end do
call cpu_time(end_time)
print '(A, F20.8)', 'Explicit loop time [s]: ', end_time - start_time
print '(A, F20.8)', 'Summation result: ', result
deallocate (x_sp, y_sp)
contains
subroutine get_argument(nr_values)
implicit none
integer(Kind=I8), intent(out) :: nr_values
character(len=1024) :: buffer, msg
integer :: status
if (command_argument_count() /= 1) then
write (unit=error_unit, fmt='(A)') 'error: expect number of values'
stop 2
end if
call get_command_argument(1, buffer)
read (buffer, fmt=*, iomsg=msg, iostat=status) nr_values
if (status /= 0) then
write (unit=error_unit, fmt='(2A)') 'error: ', trim(msg)
stop 3
end if
end subroutine get_argument
end program real32_vs_real64The above program is compiled and run using Fortran Package Manager (fpm):
Build the Program using FPM (Fortran Package Manager)¶
import os
root_dir = ""
root_dir = os.getcwd()code_dir = root_dir + "/" + "Fortran_Code/Section_Implicit_vs_Explicit_Loops"os.chdir(code_dir)build_status = os.system("fpm build 2>/dev/null")Run the Program using FPM (Fortran Package Manager)¶
exec_status = os.system("fpm run -- 10 2>/dev/null")Implicit loop time [s]: 0.00000200
Summation result: 9.57156563
Explicit loop time [s]: 0.00000100
Summation result: 8.58767700
exec_status = os.system("fpm run -- 100 2>/dev/null")Implicit loop time [s]: 0.00000100
Summation result: 82.67105103
Explicit loop time [s]: 0.00000100
Summation result: 78.12156677
exec_status = os.system("fpm run -- 1000 2>/dev/null")Implicit loop time [s]: 0.00000300
Summation result: 738.62194824
Explicit loop time [s]: 0.00000400
Summation result: 779.73486328
exec_status = os.system("fpm run -- 10000 2>/dev/null")Implicit loop time [s]: 0.00001100
Summation result: 7668.53564453
Explicit loop time [s]: 0.00002200
Summation result: 7716.35302734
exec_status = os.system("fpm run -- 100000 2>/dev/null")Implicit loop time [s]: 0.00010800
Summation result: 76268.64062500
Explicit loop time [s]: 0.00022100
Summation result: 76432.85156250
exec_status = os.system("fpm run -- 1000000 2>/dev/null")Implicit loop time [s]: 0.00211100
Summation result: 765269.12500000
Explicit loop time [s]: 0.00220800
Summation result: 765385.31250000
exec_status = os.system("fpm run -- 10000000 2>/dev/null")Implicit loop time [s]: 0.02267501
Summation result: 7671492.50000000
Explicit loop time [s]: 0.02569100
Summation result: 7669864.50000000
exec_status = os.system("fpm run -- 100000000 2>/dev/null")Implicit loop time [s]: 0.10609502
Summation result: 33554432.00000000
Explicit loop time [s]: 0.23883396
Summation result: 33554432.00000000