openlang

running_mean slow, time goes to memmove not arithmetic

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?

The conversation continues 1

Follow the reasoning
  1. Permalink

    It's the copy. readings(i, :) is strided, and the explicit-shape x(n) needs contiguous memory, so gfortran packs a temporary on every call and copies y back after. Try assumed-shape x(:), y(:). -Warray-temporaries shows it.

Other sides of the same question

  1. simple loops very slow, gfortran, 200000 x 64 array

    Small calibration tool, code below. Output is right but it is too slow. detrend+clip takes several seconds, rms also slower t…

    Replies 2Latest activity fortran
  2. Which build time are you quoting?

    Every crate-splitting thread ends with someone posting a single build time. There are two, and they move in different directi…

    Replies 2Latest activity rust
  3. Does this queue need a cached count?

    The only thing the caller ever asks this queue is List.length items > 8, and it asks repeatedly. The queue is one immutable O…

    Replies 2Latest activity ocaml