Post

A Quick Introduction to Parallel Programming with Julia

A hands-on tutorial to parallel programming with multithreading in julia.

A Quick Introduction to Parallel Programming with Julia

Example Julia code using multithreading

test.jl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# julia -t 4 test.jl
using LinearAlgebra
using Base.Threads

function parallel_dot_race_condition(x,y)
    global dot_product=0
    #Blocking
	@threads for i in 1:length(x)
        #Race condition, undefined behavior
		global dot_product += x[i]*y[i]
	end
	return dot_product
end

function parallel_dot_locking(x,y)
    global dot_product=0
    l = ReentrantLock()
    #Blocking
	@threads for i in 1:length(x)
        #Locking, high syncronization overhead, not useful at all
        lock(l) do
		    global dot_product += x[i]*y[i]
        end
	end
	return dot_product
end

function parallel_dot_optimal(x,y)
    n = nthreads()
	partial_sums = zeros(n)
    #Blocking
	@threads for i in 1:length(x)
		partial_sums[threadid()] += x[i]*y[i]
	end
    dot_product=sum(partial_sums)
	return dot_product
end

len_vec=10^6
a=rand(len_vec)
b=rand(len_vec)

#=
Necessary to time the execution of multiple tests, 
as calling a function for the first time involves 
just-in-time (JIT) compilation
=#

println("\n\n\n\nSerial TESTS =======================")
println("\nFirst parallel test (includes compilation):")
println(@time dot(a,b))
println("\nSecond serial test (no compilation):")
println(@time dot(a,b))
println("\nThird serial test (no compilation):")
println(@time dot(a,b))

println("\n\n\nINCORRECT PARALLEL TESTS =======================")
println("\nFirst parallel test (includes compilation):")
println(@time parallel_dot_race_condition(a,b))
println("\nSecond parallel test (no compilation):")
println(@time parallel_dot_race_condition(a,b))
println("\nThird parallel test (no compilation):")
println(@time parallel_dot_race_condition(a,b))

println("\n\n\n\nSUBOPTIMAL PARALLEL TESTS =======================")
println("\nFirst parallel test (includes compilation):")
println(@time parallel_dot_locking(a,b))
println("\nSecond parallel test (no compilation):")
println(@time parallel_dot_locking(a,b))
println("\nThird parallel test (no compilation):")
println(@time parallel_dot_locking(a,b))

println("\n\n\n\nOPTIMAL PARALLEL TESTS =======================")
println("\nFirst parallel test (includes compilation):")
println(@time parallel_dot_optimal(a,b))
println("\nSecond parallel test (no compilation):")
println(@time parallel_dot_optimal(a,b))
println("\nThird parallel test (no compilation):")
println(@time parallel_dot_optimal(a,b))

If you want to execute this, type the following into your terminal:

1
# julia -t 16 test.jl
This post is licensed under CC BY 4.0 by the author.