Сглаживаю данные датчиков. Массив readings(nstation, ntime), станция первым индексом, потому что так устроен файл с данными и его читают другие инструменты. Один цикл по станциям, для каждой вызываю running_mean:
do i = 1, nstation
call running_mean(readings(i, :), ntime, window, smooth(i, :))
end do
а в модуле:
subroutine running_mean(x, n, w, y)
integer, intent(in) :: n, w
real(dp), intent(in) :: x(n)
real(dp), intent(out) :: y(n)
Размеры: 1500 станций, 20000 отсчётов, окно 32. Занимает около 1.9 с, Release, -O2, gfortran из Homebrew, Apple silicon. Арифметики на отсчёт совсем немного, так что это слишком медленно.
Я сделал копию программы с массивом (ntime, nstation). Больше ничего не менял. Работает в несколько раз быстрее.
Профайлер показывает большую долю в вызовах вроде memmove/memcpy, а не в running_mean. Я этого не понимаю. Цикл в running_mean идёт по k по порядку, снаружи только один цикл. Пробовал менять -O2 и профиль CMake, без эффекта. Расход памяти тоже выглядит выше, чем я ожидаю, но я его не измерял.
Куда на самом деле уходит время? Можно ли оставить раскладку (nstation, ntime)?