``````using BenchmarkTools

versioninfo(verbose=true)
``````

### HWloc

``````using Pkg

using Hwloc
Hwloc.num_physical_cores()
``````

``````using Base.Threads

a=zeros(4)
end
a
``````

``````    @threads for i in 1:nthreads()
end
``````

#### Prefix sum

``````function prefix_threads!(y)
l=length(y)
k=ceil(Int, log2(l))
for j=1:k
@inbounds y[i] = y[i-2^(j-1)] + y[i]
end
end
for j=(k-1):-1:1
@inbounds y[i] = y[i-2^(j-1)] + y[i]
end
end
y
end
``````

### Monte Carlo

``````using Random
function darts_in_circle(n, rng=Random.GLOBAL_RNG)
inside = 0
for i in 1:n
if rand(rng)^2 + rand(rng)^2 < 1
inside += 1
end
end
return inside
end

function pi_serial(n)
return 4 * darts_in_circle(n) / n
end

const rnglist = [MersenneTwister() for i in 1:nthreads()];

inside = zeros(Int, loops)
end
return 4 * sum(inside) / (n*loops)
end

@btime pi_serial(10_000_000)

``````

### Atomics

`````` function sum_thread_base(x)
r = zero(eltype(x))
@inbounds r += x[i]
end
return r
end

a=rand(10_000_000);

@btime sum(\$a)

r = Atomic{eltype(x)}(zero(eltype(x)))
end
return r[]
end

r = Atomic{eltype(A)}(zero(eltype(A)))
#Split the array equally among the threads
r[] = zero(eltype(A))
@simd for i in (1:len) .+ (t-1)*len
@inbounds r[] += A[i]
end
end
result = r[]
#process up the remaining data
@simd for i in length(A)-rem+1:length(A)
@inbounds result += A[i]
end
return result
end

``````

### Synchronisation primitives

``````const f = open(tempname(), "a+")

r = pi_serial(10_000_000)
lock(mt)
write(f, "From \$(threadid()), pi = \$r\n")
unlock(mt)
end

close(f)

const s = Base.Semaphore(2);
Base.acquire(s)
r = pi_serial(10_000_000)
Base.release(s)
end
``````

``````a = rand(1000, 1000);

b = rand(1000, 1000);

@btime \$a*\$b;
``````

### Oversubscriptions

``````function matmul_serial(x)
first_num = zeros(length(x))
for i in eachindex(x)
@inbounds first_num[i] = (x[i]'*x[i])
end
return first_num
end

first_num = zeros(length(x))
@inbounds first_num[i] = (x[i]'*x[i])
end
return first_num
end

m = [rand(1000, 1000) for _ in 1:10];

@btime matmul_serial(m);