Skip to content

Commit b230953

Browse files
authored
Add 1:1 benchmarks results (#37)
1 parent bbab5a8 commit b230953

File tree

1 file changed

+92
-52
lines changed

1 file changed

+92
-52
lines changed

examples/benchmark_w_matlab.jl

+92-52
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
21
## Comparing the performance of the Julia and MATLAB implementations
32

43
# We can compare the performance of the Julia and MATLAB implementations
54
# by running the same model for the same number of epochs and measuring
65
# the time taken.
76

8-
using BeforeIT, Plots, Statistics
7+
using BeforeIT, CairoMakie, Statistics, ThreadPinning
8+
9+
pinthreads(:cores)
910

1011
function run(parameters, initial_conditions, T; multi_threading = false)
1112
model = BeforeIT.init_model(parameters, initial_conditions, T)
@@ -20,66 +21,105 @@ end
2021

2122
parameters = BeforeIT.AUSTRIA2010Q1.parameters
2223
initial_conditions = BeforeIT.AUSTRIA2010Q1.initial_conditions
23-
T = 12
24+
T = 12
2425

2526
# We run the code to compile it first
2627
@time run(parameters, initial_conditions, T; multi_threading = false);
2728
@time run(parameters, initial_conditions, T; multi_threading = true);
2829

2930
# Time taken by the MATLAB code and the Generated C code with MATLAB Coder
30-
# (6 threads for the parallel version), computed independently on an AMD Ryzen 5 5600H
31-
matlab_times = [4.399592, 4.398576, 4.352314, 4.385039, 4.389989]
32-
matlab_time = mean(matlab_times)
33-
matlab_time_std = std(matlab_times)
34-
35-
c_times = [0.952, 0.940, 0.951, 0.942, 0.938]
36-
c_time = mean(c_times)
37-
c_time_std = std(c_times)
38-
39-
c_times_multi_thread = [0.305, 0.324, 0.330, 0.334, 0.323]
40-
c_time_multi_thread = mean(c_times_multi_thread)
41-
c_time_multi_thread_std = std(c_times_multi_thread)
42-
43-
# Time taken by the Julia code (same platform as in the the matlab benchmarks),
31+
# (4 threads for the parallel version), computed independently on an
32+
# AMD Ryzen 5 5600H
33+
matlab_times_small = [4.399592, 4.398576, 4.352314, 4.385039, 4.389989] ./ T
34+
matlab_times_big = [2000.189556, 1990.485305, 2002.295329, 1994.215843, 1993.651854]
35+
matlab_mtime_small = mean(matlab_times_small)
36+
matlab_stime_small = std(matlab_times_small)
37+
matlab_mtime_big = mean(matlab_times_big)
38+
matlab_stime_big = std(matlab_times_big)
39+
40+
c_times_small = [0.952, 0.940, 0.951, 0.942, 0.938] ./ T
41+
c_times_big = [574.692, 576.725, 572.382, 573.921, 575.949]
42+
c_mtime_small = mean(c_times_small)
43+
c_stime_small = std(c_times_small)
44+
c_mtime_big = mean(c_times_big)
45+
c_stime_big = std(c_times_big)
46+
47+
c_times_small_multi = [0.305, 0.324, 0.330, 0.334, 0.323] ./ T
48+
c_times_big_multi = [209.603, 210.197, 209.610, 211.759, 209.174]
49+
c_mtime_small_multi = mean(c_times_small_multi)
50+
c_stime_small_multi = std(c_times_small_multi)
51+
c_mtime_big_multi = mean(c_times_big_multi)
52+
c_stime_big_multi = std(c_times_big_multi)
53+
54+
# timings from "High-performance computing implementations of agent-based
55+
# economic models for realizing 1: 1 scale simulations of large
56+
# economies", A. Gill et al. (2021)
57+
hpc_mtime_big_multi = 22.92
58+
hpc_mtime_big = hpc_mtime_big_multi*4
59+
60+
# Time taken by the Julia code (same platform as in the matlab benchmarks),
4461
# computed as the average of 5 runs
4562
n_runs = 5
4663

47-
julia_times_1_thread = zeros(n_runs)
64+
julia_times_small = zeros(n_runs)
4865
for i in 1:n_runs
49-
julia_times_1_thread[i] = @elapsed run(parameters, initial_conditions, T; multi_threading = false);
66+
julia_times_small[i] = @elapsed run(parameters, initial_conditions, T; multi_threading = false);
5067
end
51-
julia_time_1_thread = mean(julia_times_1_thread)
52-
julia_time_1_thread_std = std(julia_times_1_thread)
53-
54-
julia_times_multi_thread = zeros(n_runs)
68+
julia_times_small ./= T
69+
julia_times_big = [56.593792, 56.297404, 54.682004, 55.079674, 55.192496]
70+
julia_mtime_small = mean(julia_times_small)
71+
julia_stime_small = std(julia_times_small)
72+
julia_mtime_big = mean(julia_times_big)
73+
julia_stime_big = std(julia_times_big)
74+
75+
julia_times_small_multi = zeros(n_runs)
5576
for i in 1:5
56-
julia_times_multi_thread[i] = @elapsed run(parameters, initial_conditions, T; multi_threading = true);
77+
julia_times_small_multi[i] = @elapsed run(parameters, initial_conditions, T; multi_threading = true);
5778
end
58-
julia_time_multi_thread = mean(julia_times_multi_thread)
59-
julia_time_multi_thread_std = std(julia_times_multi_thread)
60-
61-
# Get the number of threads used
62-
n_threads = Threads.nthreads()
63-
64-
theme(:default, bg = :white)
65-
66-
# Bar chart of the time taken vs the time taken by the MATLAB code, also plot the stds as error bars
67-
bar(
68-
["MATLAB", "Gen. C, 1 thread", "Gen. C, 6 threads", "Julia, 1 thread", "Julia, $n_threads threads"],
69-
[matlab_time, c_time, c_time_multi_thread, julia_time_1_thread, julia_time_multi_thread],
70-
yerr = [matlab_time_std, c_time_std, c_time_multi_thread_std, julia_time_1_thread_std, julia_time_multi_thread_std],
71-
legend = false,
72-
dpi = 300,
73-
size = (400, 300),
74-
grid = false,
75-
ylabel = "Time for one simulation (s)",
76-
xtickfont = font(4),
77-
ytickfont = font(6),
78-
guidefont = font(6)
79-
)
80-
81-
# Save the image
82-
savefig("benchmark_w_matlab.png")
83-
84-
# The Julia implementation is faster than the MATLAB implementation, and the multi-threaded version is
85-
# faster than the single-threaded version.
79+
julia_times_small_multi ./= T
80+
julia_times_big_multi = [35.775353, 34.933283, 35.594063, 35.469412, 35.521846]
81+
julia_mtime_small_multi = mean(julia_times_small_multi)
82+
julia_stime_small_multi = std(julia_times_small_multi)
83+
julia_mtime_big_multi = mean(julia_times_big_multi)
84+
julia_stime_big_multi = std(julia_times_big_multi)
85+
86+
87+
labels = ["MATLAB", "Gen. C, 1 core", "Gen. C, 4 cores", "HPC, 1 core*", "HPC, 4 cores*",
88+
"BeforeIT.jl, 1 core", "BeforeIT.jl, 4 cores"]
89+
90+
# Create the layout
91+
fig = Figure(size = (800, 400));
92+
93+
ax1 = Axis(fig[1, 1], ylabel="time for one epoch (s)", title="Model with 8 thousands agents")
94+
ax2 = Axis(fig[1, 2], title="Model with 8 millions agents")
95+
96+
times_small = [matlab_mtime_small, c_mtime_small, c_mtime_small_multi, julia_mtime_small, julia_mtime_small_multi]
97+
barplot!(ax1,
98+
1:5,
99+
times_small,
100+
bar_labels = :y,
101+
);
102+
ylims!(ax1, 0, 1.15*maximum(times_small))
103+
104+
ax1.yticklabelspace = 25.0
105+
ax1.xticks = (1:5, [labels[1:3]..., labels[6:end]...])
106+
ax1.xticklabelrotation = 45.0
107+
ax1.xgridvisible = false
108+
109+
times_big = [matlab_mtime_big, c_mtime_big, c_mtime_big_multi, hpc_mtime_big, hpc_mtime_big_multi,
110+
julia_mtime_big, julia_mtime_big_multi]
111+
112+
ylims!(ax2, 0, 1.15*maximum(times_big))
113+
barplot!(ax2,
114+
1:7,
115+
round.(times_big, digits=1),
116+
bar_labels = :y
117+
);
118+
ax2.xticks = (1:7, labels)
119+
ax2.xticklabelrotation = 45.0
120+
ax2.xgridvisible = false
121+
122+
# Save or display the layout
123+
display(fig)
124+
125+
save("benchmark_w_matlab.png", fig)

0 commit comments

Comments
 (0)