Benchmarks ASSOC_LEGENDRE_NORM_ALL (batch) against looped
ASSOC_LEGENDRE (single-mode) calls, for , swept over NX points (one grid
sweep per timing, repeated/calibrated per WALL_TIME).
LMAX N_MODES T_BATCH T_LOOP SPEEDUP (seconds per grid-point
evaluation).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=i4), | intent(in) | :: | LMAX |
Maximum degree benchmarked, . |
||
| integer(kind=i4), | intent(in) | :: | NX |
Number of points swept per timing measurement. |
||
| integer(kind=i4), | intent(in) | :: | OUTUNIT |
Fortran unit number to append one result row to: |
SUBROUTINE BENCH_LEGENDRE(LMAX, NX, OUTUNIT) IMPLICIT NONE INTEGER(KIND=i4), INTENT(IN) :: LMAX INTEGER(KIND=i4), INTENT(IN) :: NX INTEGER(KIND=i4), INTENT(IN) :: OUTUNIT INTEGER(KIND=i4) :: L, M, IX, R, NREP, PSIZE REAL(KIND=dp) :: X, DX, T0, T1, T_BATCH, T_LOOP, ACC REAL(KIND=dp), ALLOCATABLE :: PNORM(:) PSIZE = (LMAX+1)*(LMAX+2)/2 ALLOCATE(PNORM(PSIZE)) DX = 1.8_dp / (NX - 1) ! ── Batch: one ASSOC_LEGENDRE_NORM_ALL call per grid point ────────────── NREP = 1 DO T0 = WALL_TIME() DO R = 1, NREP DO IX = 0, NX-1 X = -0.9_dp + IX*DX CALL ASSOC_LEGENDRE_NORM_ALL(PNORM, LMAX, X) ENDDO ENDDO T1 = WALL_TIME() IF (T1-T0 >= MIN_TIME .OR. NREP >= NREP_CAP) EXIT NREP = NREP*2 ENDDO T_BATCH = (T1-T0) / (NREP*NX) ACC = SUM(PNORM) IF (ACC == -1.0d300) WRITE(*,'(A)') "" !- defeat dead-code elimination ! ── Loop: ASSOC_LEGENDRE called once per (l,m) at each grid point ─────── ! (skipped above LOOP_LMAX_CAP -- see its declaration for why) IF (LMAX <= LOOP_LMAX_CAP) THEN NREP = 1 DO ACC = 0.d0 T0 = WALL_TIME() DO R = 1, NREP DO IX = 0, NX-1 X = -0.9_dp + IX*DX DO L = 0, LMAX DO M = 0, L ACC = ACC + ASSOC_LEGENDRE(L, M, X) ENDDO ENDDO ENDDO ENDDO T1 = WALL_TIME() IF (T1-T0 >= MIN_TIME .OR. NREP >= NREP_CAP) EXIT NREP = NREP*2 ENDDO T_LOOP = (T1-T0) / (NREP*NX) IF (ACC == -1.0d300) WRITE(*,'(A)') "" ELSE T_LOOP = -1.0_dp !- sentinel: not measured, see LOOP_LMAX_CAP END IF IF (T_LOOP >= 0.0_dp) THEN WRITE(OUTUNIT,'(I6,1X,I8,1X,ES14.6,1X,ES14.6,1X,F12.3)') & LMAX, PSIZE, T_BATCH, T_LOOP, T_LOOP/T_BATCH ELSE WRITE(OUTUNIT,'(I6,1X,I8,1X,ES14.6,1X,ES14.6,1X,F12.3)') & LMAX, PSIZE, T_BATCH, T_LOOP, -1.0_dp END IF DEALLOCATE(PNORM) RETURN END SUBROUTINE BENCH_LEGENDRE