mirror of
https://gitlab.rlp.net/mobitar/julia_course.git
synced 2024-11-16 13:28:10 +00:00
Added performance demos
This commit is contained in:
parent
f748185f62
commit
7ad274779b
1 changed files with 283 additions and 3 deletions
286
Day_4/Day_4.jl
286
Day_4/Day_4.jl
|
@ -4,6 +4,12 @@
|
|||
using Markdown
|
||||
using InteractiveUtils
|
||||
|
||||
# ╔═╡ 7a9ccfbc-bd2e-41d0-be5d-dea04b90d397
|
||||
using BenchmarkTools
|
||||
|
||||
# ╔═╡ 8b1dfee2-bd8b-4d23-b9f8-9406002e0eaa
|
||||
using Random
|
||||
|
||||
# ╔═╡ 1fb7d9af-333e-44f2-b693-09ff97937d4c
|
||||
# Oh, no, you found my secret! 😱
|
||||
# Don't change this hidden cell!
|
||||
|
@ -135,8 +141,164 @@ If you want syntax highlighting in your REPL, add the package `OhMyREPL` to your
|
|||
https://kristofferc.github.io/OhMyREPL.jl/latest/installation/
|
||||
"""
|
||||
|
||||
# ╔═╡ d21771de-272e-4d57-8c76-c75be709ad0a
|
||||
# ╔═╡ 0e53e4ee-16a7-47ef-9992-77cbfd1ed258
|
||||
md"""
|
||||
# Benchmarking
|
||||
"""
|
||||
|
||||
# ╔═╡ d86e4a2f-e737-49a4-bc16-a149e81785bd
|
||||
function normal_for_loop(N)
|
||||
factorials = zeros(BigInt, N)
|
||||
|
||||
for i in 1:N
|
||||
factorials[i] = factorial(big(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
# ╔═╡ bc777c73-9573-41c3-8ab5-843335539f96
|
||||
N = 5000
|
||||
|
||||
# ╔═╡ 55d1d616-b6ee-40dd-a0ed-6274a98b1e73
|
||||
@benchmark normal_for_loop(N)
|
||||
|
||||
# ╔═╡ 00c27927-9c72-417a-862f-9b66318d9751
|
||||
@btime normal_for_loop(N)
|
||||
|
||||
# ╔═╡ d21771de-272e-4d57-8c76-c75be709ad0a
|
||||
md"""
|
||||
# Multithreading
|
||||
Julia is built as a modern language with parallel and asynchronous programming in mind.
|
||||
|
||||
You can use run Julia code on the GPU, on multiple CPU threads (multithreading) and with multiple processes (multiprocessing).
|
||||
|
||||
In this course, only multithreading will be presented.
|
||||
|
||||
The easiest way to use multithreading in Julia is by letting a `for` loop run on multiple threads. This can be achieved by only addy the macro `@threads` before the `for` loop.
|
||||
|
||||
Before trying to use multithreading, make sure that you launch Julia with multiple threads. To do so, run the following to launch Julia:
|
||||
|
||||
julia -t auto
|
||||
|
||||
You can append `--project=.` and other arguments to it.
|
||||
|
||||
`-t` is an alias to `--threads`. `auto` automatically determins how many threads your PC supports. You can also replace `auto` by the number of threads that you want to use. This number can not be bigger than the number of threads that your computer supports.
|
||||
"""
|
||||
|
||||
# ╔═╡ 2cf5f891-8d8f-477d-8ef1-9b4b9480d477
|
||||
# Show available number of threads
|
||||
# If this is 1, then you can not use multithreading!
|
||||
# If your PC has only one core and one thread, then you can do nothing about it.
|
||||
# Otherwise, you have to tell Julia how many threads to use with the `-t` argument.
|
||||
Threads.nthreads()
|
||||
|
||||
# ╔═╡ 76866972-0290-4e33-93de-b6128ba11994
|
||||
md"""
|
||||
## `@threads`
|
||||
"""
|
||||
|
||||
# ╔═╡ cacc94b4-21e0-410e-acaa-80e37b447f94
|
||||
function multithreaded_for_loop(N)
|
||||
factorials = zeros(BigInt, N)
|
||||
|
||||
Threads.@threads for i in 1:N
|
||||
factorials[i] = factorial(big(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
# ╔═╡ a3029480-bcdc-44f3-b504-8bd3bf3aa14d
|
||||
@btime multithreaded_for_loop(N)
|
||||
|
||||
# ╔═╡ f141dbb4-bdc5-4f16-8d97-fc0a3d5981f2
|
||||
function shuffle_multithreaded_for_loop(N)
|
||||
factorials = zeros(BigInt, N)
|
||||
|
||||
Threads.@threads for i in shuffle(1:N)
|
||||
factorials[i] = factorial(big(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
# ╔═╡ e9dcda88-1eef-4c0a-99b2-12eaec56186b
|
||||
@btime shuffle_multithreaded_for_loop(N)
|
||||
|
||||
# ╔═╡ 009bb2e8-f03e-40f7-a66b-166dc6a1962d
|
||||
md"""
|
||||
## Thread safety
|
||||
"""
|
||||
|
||||
# ╔═╡ dd5e5073-be29-47e7-91c5-9e47c35f905c
|
||||
function thread_unsafe()
|
||||
N = 100000
|
||||
var = 0
|
||||
|
||||
Threads.@threads for i in 1:N
|
||||
var += 1
|
||||
end
|
||||
|
||||
return var
|
||||
end
|
||||
|
||||
# ╔═╡ 4554cbf0-36f5-45c6-a966-ad18b1592a60
|
||||
# Run this cell multiple times.
|
||||
# The output is random 🤯
|
||||
thread_unsafe()
|
||||
|
||||
# ╔═╡ ec08a80c-8886-4312-9481-5c89951681e1
|
||||
function thread_unsafe_sum(N)
|
||||
sum_of_sums = 0
|
||||
|
||||
Threads.@threads for i in 1:N
|
||||
sum_of_sums = sum(1:i)
|
||||
end
|
||||
|
||||
return sum_of_sums
|
||||
end
|
||||
|
||||
# ╔═╡ 3b5d9f7c-1fc9-4e85-8c07-8b5709895a10
|
||||
N2 = 1000000
|
||||
|
||||
# ╔═╡ fbd2423b-aaea-47a7-a3cf-537860e11a93
|
||||
thread_unsafe_sum(N2)
|
||||
|
||||
# ╔═╡ e65ad214-33ba-4d08-81f0-5f98022a9f78
|
||||
function thread_safe_sum(N)
|
||||
sums = zeros(Int64, N)
|
||||
|
||||
Threads.@threads for i in 1:N
|
||||
sums[i] = sum(1:i)
|
||||
end
|
||||
|
||||
return sum(sums)
|
||||
end
|
||||
|
||||
# ╔═╡ 8ad3daa6-d221-4ff7-9bc2-8e8a66bdd8c7
|
||||
@btime thread_safe_sum(N2)
|
||||
|
||||
# ╔═╡ 95dffc7f-3393-487e-8521-c96291cdc7bf
|
||||
typemax(Int64)
|
||||
|
||||
# ╔═╡ ebd3a9d9-7a12-4001-9b53-913f664fb1c8
|
||||
function shuffle_safe_thread_sum(N)
|
||||
sums = zeros(Int64, N)
|
||||
|
||||
Threads.@threads for i in shuffle(1:N)
|
||||
sums[i] = sum(1:i)
|
||||
end
|
||||
|
||||
return sum(sums)
|
||||
end
|
||||
|
||||
# ╔═╡ ddd2409e-de34-4eb9-a0b7-e10cc6c0ce9f
|
||||
# This is worse than the version without shuffeling.
|
||||
# In this case, shuffling is too expensive compared with its benefit
|
||||
# Especially for multithreading, there is no silver bullet.
|
||||
# Always benchmark! This is the only method to make sure that an "optimization" indeed an optimization is
|
||||
@btime shuffle_safe_thread_sum(N2)
|
||||
|
||||
# ╔═╡ 09f71a9e-6798-492f-98df-45087d0c4c8b
|
||||
md"""
|
||||
|
@ -146,15 +308,94 @@ Julia has a focus on high performance. But if you don't pay attention, you might
|
|||
In this section, tools and tips for performance optimization in Julia are presented.
|
||||
"""
|
||||
|
||||
# ╔═╡ 2a24aebc-0654-4d00-bdab-627a8e1a75f2
|
||||
# ╔═╡ 6509dddd-ff17-49db-8e5e-fcea1ef0026c
|
||||
N3 = 1000000
|
||||
|
||||
# ╔═╡ 2a24aebc-0654-4d00-bdab-627a8e1a75f2
|
||||
begin
|
||||
sin_vals = []
|
||||
|
||||
function global_allocating_access(N)
|
||||
for i in 1:N
|
||||
push!(sin_vals, sin(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@btime global_allocating_access(N3)
|
||||
end
|
||||
|
||||
# ╔═╡ 56058ab1-4ea2-479d-88f9-5da6ac8c39c2
|
||||
begin
|
||||
typed_sin_vals = Float64[]
|
||||
|
||||
function typed_global_allocating_access(N)
|
||||
for i in 1:N
|
||||
push!(typed_sin_vals, sin(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@btime typed_global_allocating_access(N3)
|
||||
end
|
||||
|
||||
# ╔═╡ ef164e7c-668a-4312-83f1-687ca7d4c8f9
|
||||
begin
|
||||
preallocated_sin_vals = zeros(Float64, N3)
|
||||
|
||||
function global_preallocated_access(N)
|
||||
for i in 1:N
|
||||
preallocated_sin_vals[i] = sin(i)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@btime global_preallocated_access(N3)
|
||||
end
|
||||
|
||||
# ╔═╡ ebc621b5-3aa3-4cf7-bcdf-e4c5fbb79f50
|
||||
begin
|
||||
passed_preallocated_sin_vals = zeros(Float64, N3)
|
||||
|
||||
function local_preallocated_access(N, sin_vals)
|
||||
for i in 1:N
|
||||
sin_vals[i] = sin(i)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@btime local_preallocated_access(N3, passed_preallocated_sin_vals)
|
||||
end
|
||||
|
||||
# ╔═╡ afcc15de-81e0-484f-80cf-3d805517c6e8
|
||||
# Here, the difference of preallocation is clearer
|
||||
begin
|
||||
passed_sin_vals = Float64[]
|
||||
|
||||
function local_access(N, sin_vals)
|
||||
for i in 1:N
|
||||
push!(sin_vals, sin(i))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@btime local_access(N3, passed_sin_vals)
|
||||
end
|
||||
|
||||
# ╔═╡ 00000000-0000-0000-0000-000000000001
|
||||
PLUTO_PROJECT_TOML_CONTENTS = """
|
||||
[deps]
|
||||
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
|
||||
[compat]
|
||||
BenchmarkTools = "~1.3.1"
|
||||
PlutoUI = "~0.7.38"
|
||||
"""
|
||||
|
||||
|
@ -180,6 +421,12 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
|||
[[deps.Base64]]
|
||||
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
|
||||
[[deps.BenchmarkTools]]
|
||||
deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"]
|
||||
git-tree-sha1 = "4c10eee4af024676200bc7752e536f858c6b8f93"
|
||||
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||
version = "1.3.1"
|
||||
|
||||
[[deps.ColorTypes]]
|
||||
deps = ["FixedPointNumbers", "Random"]
|
||||
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
|
||||
|
@ -298,6 +545,10 @@ version = "0.7.38"
|
|||
deps = ["Unicode"]
|
||||
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||
|
||||
[[deps.Profile]]
|
||||
deps = ["Printf"]
|
||||
uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
|
||||
|
||||
[[deps.REPL]]
|
||||
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
|
||||
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||
|
@ -369,9 +620,38 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
|||
# ╟─7f45c502-0909-42df-b93d-384f743df6a9
|
||||
# ╟─f23ad33d-af1d-40c2-9efc-17ef8c4d1fb8
|
||||
# ╟─6340aec8-6f77-4a30-8815-ce76ddecd6e8
|
||||
# ╠═d21771de-272e-4d57-8c76-c75be709ad0a
|
||||
# ╠═0e53e4ee-16a7-47ef-9992-77cbfd1ed258
|
||||
# ╠═7a9ccfbc-bd2e-41d0-be5d-dea04b90d397
|
||||
# ╠═d86e4a2f-e737-49a4-bc16-a149e81785bd
|
||||
# ╠═bc777c73-9573-41c3-8ab5-843335539f96
|
||||
# ╠═55d1d616-b6ee-40dd-a0ed-6274a98b1e73
|
||||
# ╠═00c27927-9c72-417a-862f-9b66318d9751
|
||||
# ╟─d21771de-272e-4d57-8c76-c75be709ad0a
|
||||
# ╠═2cf5f891-8d8f-477d-8ef1-9b4b9480d477
|
||||
# ╟─76866972-0290-4e33-93de-b6128ba11994
|
||||
# ╠═cacc94b4-21e0-410e-acaa-80e37b447f94
|
||||
# ╠═a3029480-bcdc-44f3-b504-8bd3bf3aa14d
|
||||
# ╠═8b1dfee2-bd8b-4d23-b9f8-9406002e0eaa
|
||||
# ╠═f141dbb4-bdc5-4f16-8d97-fc0a3d5981f2
|
||||
# ╠═e9dcda88-1eef-4c0a-99b2-12eaec56186b
|
||||
# ╠═009bb2e8-f03e-40f7-a66b-166dc6a1962d
|
||||
# ╠═dd5e5073-be29-47e7-91c5-9e47c35f905c
|
||||
# ╠═4554cbf0-36f5-45c6-a966-ad18b1592a60
|
||||
# ╠═ec08a80c-8886-4312-9481-5c89951681e1
|
||||
# ╠═3b5d9f7c-1fc9-4e85-8c07-8b5709895a10
|
||||
# ╠═fbd2423b-aaea-47a7-a3cf-537860e11a93
|
||||
# ╠═e65ad214-33ba-4d08-81f0-5f98022a9f78
|
||||
# ╠═8ad3daa6-d221-4ff7-9bc2-8e8a66bdd8c7
|
||||
# ╠═95dffc7f-3393-487e-8521-c96291cdc7bf
|
||||
# ╠═ebd3a9d9-7a12-4001-9b53-913f664fb1c8
|
||||
# ╠═ddd2409e-de34-4eb9-a0b7-e10cc6c0ce9f
|
||||
# ╟─09f71a9e-6798-492f-98df-45087d0c4c8b
|
||||
# ╠═6509dddd-ff17-49db-8e5e-fcea1ef0026c
|
||||
# ╠═2a24aebc-0654-4d00-bdab-627a8e1a75f2
|
||||
# ╠═56058ab1-4ea2-479d-88f9-5da6ac8c39c2
|
||||
# ╠═ef164e7c-668a-4312-83f1-687ca7d4c8f9
|
||||
# ╠═ebc621b5-3aa3-4cf7-bcdf-e4c5fbb79f50
|
||||
# ╠═afcc15de-81e0-484f-80cf-3d805517c6e8
|
||||
# ╟─1fb7d9af-333e-44f2-b693-09ff97937d4c
|
||||
# ╟─00000000-0000-0000-0000-000000000001
|
||||
# ╟─00000000-0000-0000-0000-000000000002
|
||||
|
|
Loading…
Reference in a new issue