Очевидное место для установки прагмы omp - в самом внешнем цикле.
Для каждого (l, m, n) вы вычисляете свертку между возмущенными переменными и экспоненциальным сглаживателем.Каждое вычисление (l, m, n) совершенно не зависит от других, поэтому вы можете поместить его в самый внешний цикл.Так, например, самая простая вещь
!$omp parallel do private(n,m,l,i,j,k,exp_smoother) shared(sum_u_pert,sum_v_pert,sum_t_pert,u_p,v_p,t_p), default(none)
do n=1,lm
do m=1,jm
do l=1,im
do k=1,lm
do j=1,jm
do i=1,im
exp_smoother=exp(-(abs(i-l)/hzscl)-(abs(j-m)/hzscl)-(abs(k-n)/vscl))
sum_u_pert(l,m,n) = sum_u_pert(l,m,n) + u_p(i,j,k) * exp_smoother
sum_v_pert(l,m,n) = sum_v_pert(l,m,n) + v_p(i,j,k) * exp_smoother
sum_t_pert(l,m,n) = sum_t_pert(l,m,n) + t_p(i,j,k) * exp_smoother
end do
end do
end do
end do
end do
end do
дает мне ~ 6-кратное ускорение на 8 ядрах (при использовании значительно уменьшенного размера задачи 20x41x41).Учитывая объем работы, которую необходимо выполнить в циклах, даже при меньшем размере, я предполагаю, что причина не в том, что ускорение в 8 раз связано с нехваткой памяти или ошибочным совместным использованием;для дальнейшей настройки производительности вы можете явно разбить массивы сумм на подблоки для каждого потока и объединить их в конце;но в зависимости от размера задачи наличие дополнительного массива im x jm x lm может быть нежелательным.
Похоже, что в этой задаче есть много структур, которые вы могли бы изучитьускорить даже серийный случай, но легче сказать это, чем найти его;играя с ручкой и бумагой, через несколько минут ничего не приходит в голову, но кто-то умнее может что-то заметить.