The biggest problem seems to be the main loop in calc_net.jl:
for idx = 1:numO
o = o_vec[idx]
# conditions in which something occurs
cond_A_su = (o .< b_hist[:,3]) & (b_hist[:,1] .== 65)
cond_B_su = (o .> b_hist[:,3]) & (b_hist[:,1] .== 66)
# conditions in which something occurs
cond_A_pu = (o .== b_hist[:,3]) & (b_hist[:,1] .== 65)
cond_B_pu = (o .== b_hist[:,3]) & (b_hist[:,1] .== 66)
# sum stuff according to conditions
b_A_su_[idx] = sum(b_hist_col2 .* cond_A_su)
b_B_su_[idx] = sum(b_hist_col2 .* cond_B_su)
# sum stuff according to conditions
b_A_pu_[idx] = sum(b_hist_col2 .* cond_A_pu)
b_B_pu_[idx] = sum(b_hist_col2 .* cond_B_pu)
end # idx
Every single instance of .* , .== and .> creates a new for-loop in the
machine code produced by Julia and each one requires the creation of a new
temporary variable. In Matlab this is a necessary evil because native
Matlab loops are so slow. But Julia loops are fast, so you should write
this code the way you would write it in C or Fortran:
# sum stuff according to conditions
b_A_su_[idx] = 0
b_B_su_[idx] = 0
# sum stuff according to conditions
b_A_pu_[idx] = 0
b_B_pu_[idx] = 0
for j in 1:length(b_hist[:,3])
# conditions in which something occurs
cond_A_su = (o < b_hist[j,3]) & (b_hist[j,1] .== 65)
cond_B_su = (o > b_hist[j,3]) & (b_hist[j,1] .== 66)
# conditions in which something occurs
cond_A_pu = (o == b_hist[j,3]) & (b_hist[j,1] .== 65)
cond_B_pu = (o == b_hist[j,3]) & (b_hist[j,1] .== 66)
# sum stuff according to conditions
b_A_su_[idx] += b_hist_col2[j] * cond_A_su
b_B_su_[idx] += b_hist_col2[j] * cond_B_su
# sum stuff according to conditions
b_A_pu_[idx] += b_hist_col2[j] * cond_A_pu
b_B_pu_[idx] += b_hist_col2[j] * cond_B_pu
end
On my computer, this change reduces the execution time and memory
allocation (both) by a factor of 3. So this change alone does not make the
program fast, but I think it is illustrative of the type of changes that
are needed. Another place I would look at is:
# retrieve some history
b_hist = reshape(sim["b"][d, 1:t, i, :], t, 3)
b_hist_col2 = reshape(sim["b"][d, 1:t, i, 2], t, 1)
b_hist_col2_A = b_hist_col2 .* (b_hist[:,1] .== 65)
b_hist_col2_B = b_hist_col2 .* (b_hist[:,1] .== 66)
The first two lines require memory allocation and might also have a bad
memory profile. I can't rewrite it because I'm not sure what the program is
supposed to do. The last two lines are another set of for-loops that could
be bundled together like I showed you.
In general, I think you can improve the code by switching to for-loops (as
you would in C or C++) and memory allocation.
Cheers,
Daniel.
On Saturday, 19 September 2015 19:50:50 UTC+2, Adam wrote:
>
> Hi, I'm a novice to Julia but have heard promising things and wanted to
> see if the language can help with a problem I'm working on. I have some
> Matlab code with some user-defined functions that runs a simulation in
> about ~1.4 seconds in Matlab (for a certain set of parameters that
> characterize a small problem instance). I translated the code into Julia,
> and to my surprise the Julia code runs 5x to 30x slower than the Matlab
> code. I'll be running this code on much larger problem instances many, many
> times (within some other loops), so performance is important here.
>
> I created a GitHub gist that contains a stripped-down version of the Julia
> code that gets as close to (as I can find) the culprit of the problem. The
> gist is here: https://gist.github.com/anonymous/010bcbda091381b0de9e. A
> quick description:
>
> - set_up.jl sets up parameters and other items.
> - set_up_sim.jl sets up items particular to the simulation.
> - simulation.jl runs the simulation.
> - calc_net.jl, dist_o_i.jl, and update_w.jl are user-defined functions
> executed in the simulation.
>
>
> On my laptop (running in Juno with Julia version 0.3.10), this code yields:
> elapsed time: 43.269609577 seconds (20297989440 bytes allocated, 38.77% gc
> time)
> elapsed time: 38.500054653 seconds (20291872804 bytes allocated, 40.41% gc
> time)
> elapsed time: 40.238907235 seconds (20291869252 bytes allocated, 39.44% gc
> time)
>
> Why is so much memory used, and why is so much time spent in garbage
> collection?
>
> I'm familiar with
> http://docs.julialang.org/en/release-0.3/manual/performance-tips/ and
> have tried to follow these tips to the best of my knowledge. One example of
> what might be seen as low-hanging fruit: I tried removing the type
> declarations from my functions, but this actually increased the run-time of
> the code by a few seconds. Also, other permutations of the column orders
> pertaining to D, T, and I led to slower performance.
>
> I'm sure there are several issues at play here-- I'm just using Julia for
> the first time. Any tips would be greatly appreciated.
>