Я сейчас пишу числовой решатель в Джулии. Я не думаю, что математика стоит за этим слишком много. Все сводится к тому, что определенная операция выполняется несколько раз и использует большой процент (~ 80%) времени выполнения.
Я попытался максимально уменьшить его и представить вам этот фрагмент кода, который можно сохранить как dummy.jl
, а затем выполнить с помощью include("dummy.jl")
, затем dummy(10)
(для компиляции) и затем dummy(1000)
.
function dummy(N::Int64)
A = rand(N,N)
@time timethis(A)
end
function timethis(A::Array{Float64,2})
dummyvariable = 0.0
for k=1:100 # just repeat a few times
for i=2:size(A)[1]-1
for j=2:size(A)[2]-1
dummyvariable += slopefit(A[i-1,j],A[i,j],A[i+1,j],2.0)
dummyvariable += slopefit(A[i,j-1],A[i,j],A[i,j+1],2.0)
end
end
end
println(dummyvariable)
end
@inline function minmod(x::Float64, y::Float64)
return sign(x) * max(0.0, min(abs(x),y*sign(x) ) );
end
@inline function slopefit(left::Float64,center::Float64,right::Float64,theta::Float64)
# arg=ccall((:minmod,"libminmod"),Float64,(Float64,Float64),0.5*(right-left),theta*(center-left));
# result=ccall((:minmod,"libminmod"),Float64,(Float64,Float64),theta*(right-center),arg);
# return result
tmp = minmod(0.5*(right-left),theta*(center-left));
return minmod(theta*(right-center),tmp);
#return 1.0
end
Здесь timethis
будет имитировать ту часть кода, где я провожу много времени. Я замечаю, что slopefit
чрезвычайно дорого выполнять.
Например, dummy(1000)
занимает примерно 4 секунды на моей машине. Если вместо этого slopefit
будет всегда возвращать 1
и ничего не вычислять, время сокращается до одной десятой от общего времени.
Теперь, очевидно, нет бесплатного обеда.
Мне известно, что это просто дорогостоящая операция. Но я все равно попытался бы оптимизировать его как можно больше, учитывая, что много времени тратится на то, что выглядит так, как если бы это можно было легко оптимизировать, поскольку это всего лишь несколько строк кода.
До сих пор я пытался реализовать minmod
и slopefit
как C-функции и вызывать их, однако это только увеличивало время вычислений (возможно, я сделал это неправильно).
Итак, мой вопрос: какие у меня есть возможности оптимизировать вызов slopefit
?
Обратите внимание, что в фактическом коде аргументы slopefit
не являются упомянутыми здесь, а зависят от условных операторов, которые усложняют векторизацию (если это приведет к какому-либо приросту производительности, я не уверен).