🔬
Solver Purpose & Physical Scope
Calculate scaled speedup for parallel applications where workload size grows with processing power.
📂 Discipline: Cfd
⚡ Precision: IEEE-754 64-bit Real(`real(8)`)
📥 Total Downloads: 457 times
📄 Source File:
gustafson.f90
📁 calcul/CFD /
gustafson.f90
!==============================================================================
! ThermoFluidCalc — Calculator #31 : Gustafson's Law
!==============================================================================
! S(N) = 1 + f*(N-1) (scaled speedup / weak scaling)
! Alternatively: S = s + f*N where s = 1-f
! Comparison with Amdahl: S_amdahl = 1/((1-f)+f/N)
! Reference : Gupta, §5.8, Eq. 5.95
! Build: gfortran -O2 -o gustafson gustafson.f90
!==============================================================================
program gustafson
implicit none
integer, parameter :: dp = selected_real_kind(15,307)
integer, parameter :: MX = 10000
integer :: mode, N, Nmin, Nmax, npts, i
real(dp) :: f, Sg, Sa, Eg, Ea, df, fv, dN
read(*,*) mode
select case(mode)
! MODE 1 : Single point — both laws
case(1)
backspace(5); read(*,*) mode, f, N
if(f<0) f=0; if(f>1) f=1; if(N<1) N=1
Sg = 1.0_dp + f*real(N-1,dp)
Eg = Sg / real(N,dp)
Sa = 1.0_dp / ((1.0_dp-f) + f/real(N,dp))
Ea = Sa / real(N,dp)
write(*,'(A,I1)') 'MODE=', mode
write(*,'(A)') 'MODE_NAME=Single Point'
write(*,'(A,F10.6)') 'F=', f
write(*,'(A,I8)') 'N=', N
write(*,'(A,F12.4)') 'S_GUSTAFSON=', Sg
write(*,'(A,F10.4)') 'E_GUSTAFSON=', Eg
write(*,'(A,F12.4)') 'S_AMDAHL=', Sa
write(*,'(A,F10.4)') 'E_AMDAHL=', Ea
! MODE 2 : N sweep — both laws
case(2)
backspace(5); read(*,*) mode, f, Nmin, Nmax, npts
if(f<0) f=0; if(f>1) f=1
if(Nmin<1) Nmin=1; if(Nmax<Nmin) Nmax=Nmin
if(npts<2) npts=2; if(npts>MX) npts=MX
write(*,'(A,I1)') 'MODE=', mode
write(*,'(A)') 'MODE_NAME=N Sweep'
write(*,'(A,F10.6)') 'F=', f
dN = real(Nmax-Nmin,dp)/real(npts-1,dp)
write(*,'(A)') 'DATA_START'
do i = 0, npts-1
N = Nmin + nint(real(i,dp)*dN)
if(N<1) N=1
Sg = 1.0_dp + f*real(N-1,dp)
Sa = 1.0_dp / ((1.0_dp-f) + f/real(N,dp))
Eg = Sg / real(N,dp)
write(*,'(I8,A,F12.4,A,F12.4,A,F10.6)') N, ',', Sg, ',', Sa, ',', Eg
end do
write(*,'(A)') 'DATA_END'
! MODE 3 : f sweep — both laws for fixed N
case(3)
backspace(5); read(*,*) mode, N, npts
if(N<1) N=1; if(npts<2) npts=2; if(npts>MX) npts=MX
write(*,'(A,I1)') 'MODE=', mode
write(*,'(A)') 'MODE_NAME=f Sweep'
write(*,'(A,I8)') 'N=', N
df = 1.0_dp/real(npts-1,dp)
write(*,'(A)') 'DATA_START'
do i = 0, npts-1
fv = real(i,dp)*df
Sg = 1.0_dp + fv*real(N-1,dp)
Sa = 1.0_dp / ((1.0_dp-fv) + fv/real(N,dp))
write(*,'(F10.6,A,F12.4,A,F12.4)') fv, ',', Sg, ',', Sa
end do
write(*,'(A)') 'DATA_END'
case default
write(*,'(A)') 'ERROR=Invalid mode (1-3).'; stop
end select
end program gustafson
💻 How to Compile & Run Locally
1. Compilation (GNU Fortran / Intel oneAPI):
gfortran -O3 gustafson.f90 -o gustafson
2. Execution with input.txt redirection:
gustafson < input.txt
📄 Sample input.txt File Structure
Sample Data:
0.9 8
Parameter Description:
f_in\nN (processors)