Smoothing sensor data. Array is readings(nstation, ntime), station first, because the data file is laid out so and other tools read it. One loop over stations, call running_mean for each:
do i = 1, nstation
call running_mean(readings(i, :), ntime, window, smooth(i, :))
end do
and in the module:
subroutine running_mean(x, n, w, y)
integer, intent(in) :: n, w
real(dp), intent(in) :: x(n)
real(dp), intent(out) :: y(n)
Sizes: 1500 stations, 20000 samples, window 32. Takes about 1.9 s, Release, -O2, gfortran from Homebrew, Apple silicon. Arithmetic per sample is tiny, so this is too slow.
I made a copy of the program with the array as (ntime, nstation). Nothing else changed. It ran several times faster.
Profiler shows big share in memmove/memcpy-like calls, not in running_mean. I do not understand this. Loop in running_mean walks k in order, only one loop outside. I tried changing -O2 and the CMake profile, no effect. Memory use also looks higher than I expect, but I did not measure it.
Where does the time really go? Can I keep the (nstation, ntime) layout?