🔬
Solver Purpose & Physical Scope
Compute theoretical speedup of program execution on multi-core systems using Amdahl's Law.
📂 Discipline: Cfd
⚡ Precision: IEEE-754 64-bit Real(`real(8)`)
📥 Total Downloads: 491 times
📄 Source File:
amdahl.f90
📁 calcul/CFD /
amdahl.f90
!==============================================================================
! ThermoFluidCalc — Calculator #30 : Amdahl's Law
!==============================================================================
! S(N) = 1 / ((1-f) + f/N) E = S/N S_max = 1/(1-f)
! f = parallel fraction, N = processors
! Reference : Gupta, §5.8, Eq. 5.92
! Build: gfortran -O2 -o amdahl amdahl.f90
!==============================================================================
program amdahl
implicit none
integer, parameter :: dp = selected_real_kind(15,307)
integer, parameter :: MX = 10000
integer :: mode, N, Nmin, Nmax, npts, i, n50, n80
real(dp) :: f, S, E, Smax, ser, par, fmin, fmax, df, fv
real(dp) :: Nv, dN
read(*,*) mode
select case(mode)
! MODE 1 : Single point
case(1)
backspace(5); read(*,*) mode, f, N
if(f<0) f=0; if(f>1) f=1; if(N<1) N=1
ser = 1.0_dp - f
par = f / real(N,dp)
S = 1.0_dp / (ser + par)
E = S / real(N,dp)
if(f < 1.0_dp) then; Smax = 1.0_dp/(1.0_dp-f); else; Smax = real(N,dp); end if
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)') 'SPEEDUP=', S
write(*,'(A,F10.4)') 'EFFICIENCY=', E
write(*,'(A,F12.4)') 'S_MAX=', Smax
write(*,'(A,F10.6)') 'SERIAL_FRAC=', ser
write(*,'(A,F10.6)') 'PAR_TIME=', par
write(*,'(A,F10.6)') 'TOTAL_TIME=', ser+par
! MODE 2 : Processor sweep
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
if(f<1.0_dp) then; Smax=1.0_dp/(1.0_dp-f); else; Smax=real(Nmax,dp); end if
n50=0; n80=0
write(*,'(A,I1)') 'MODE=', mode
write(*,'(A)') 'MODE_NAME=Processor Sweep'
write(*,'(A,F10.6)') 'F=', f
write(*,'(A,F12.4)') 'S_MAX=', Smax
write(*,'(A)') 'DATA_START'
dN = real(Nmax-Nmin,dp)/real(npts-1,dp)
do i = 0, npts-1
N = Nmin + nint(real(i,dp)*dN)
if(N<1) N=1
S = 1.0_dp / ((1.0_dp-f) + f/real(N,dp))
E = S / real(N,dp)
write(*,'(I8,A,F12.4,A,F10.6)') N, ',', S, ',', E
if(n50==0 .and. E<0.50_dp) n50=N
if(n80==0 .and. E<0.80_dp) n80=N
end do
write(*,'(A)') 'DATA_END'
write(*,'(A,I8)') 'N_50PCT=', n50
write(*,'(A,I8)') 'N_80PCT=', n80
! MODE 3 : f sweep
case(3)
backspace(5); read(*,*) mode, N, fmin, fmax, npts
if(N<1) N=1; if(npts<2) npts=2; if(npts>MX) npts=MX
if(fmin<0) fmin=0; if(fmax>1) fmax=1
write(*,'(A,I1)') 'MODE=', mode
write(*,'(A)') 'MODE_NAME=Fraction Sweep'
write(*,'(A,I8)') 'N=', N
df = (fmax-fmin)/real(npts-1,dp)
write(*,'(A)') 'DATA_START'
do i = 0, npts-1
fv = fmin + real(i,dp)*df
S = 1.0_dp / ((1.0_dp-fv) + fv/real(N,dp))
E = S / real(N,dp)
write(*,'(F10.6,A,F12.4,A,F10.6)') fv, ',', S, ',', E
end do
write(*,'(A)') 'DATA_END'
case default
write(*,'(A)') 'ERROR=Invalid mode (1-3).'; stop
end select
end program amdahl
💻 How to Compile & Run Locally
1. Compilation (GNU Fortran / Intel oneAPI):
gfortran -O3 amdahl.f90 -o amdahl
2. Execution with input.txt redirection:
amdahl < input.txt
📄 Sample input.txt File Structure
Sample Data:
0.9 8
Parameter Description:
f (parallel fraction, 0–1)\nN (processors)