# Simple example of @threads

**URL:** https://discourse.julialang.org/t/simple-example-of-threads/83049
**Category:** Performance
**Tags:** multithreading
**Created:** [June 20, 2022, 6:42am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049 "2022-06-20T06:42:31Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 20, 2022, 6:42am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/1 "2022-06-20T06:42:31Z")

</div>

How can I make this simple example thread safe?

```julia
function func(R=5)
    s = 0.0
    Threads.@threads :static for i in 1:R
        s += 1
    end
    return s
end

```

If it makes any difference, in my application I am summing over a very expensive function, instead of just integers.

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [June 20, 2022, 7:11am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/2 "2022-06-20T07:11:20Z")

</div>

Maybe try `ThreadsX.sum`?

> **[GitHub - tkf/ThreadsX.jl: Parallelized Base functions](https://github.com/tkf/ThreadsX.jl)**
>
> Parallelized Base functions. Contribute to tkf/ThreadsX.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 20, 2022, 8:29am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/3 "2022-06-20T08:29:29Z")

</div>

I’d like to keep the structure of a `for` loop because I have something like this:

```julia
function func(R)
    b = zero(paramvec)
    for i in 1:R
        sdata = datasimulator() # returns a vector of data
        b += estimatemodel(sdata) # returns a vector of parameters
    end
    avgb = b ./ R # averages parameters across simulations
    return likelihood(avgb)
end

```

Can that be done?

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [June 20, 2022, 9:10am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/4 "2022-06-20T09:10:34Z")

</div>

I think it can be achieved with `ThreadsX.mapreduce`

---

<div class="post-metadata">

### Author: ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)
#### Post date: [June 20, 2022, 10:27am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/5 "2022-06-20T10:27:03Z")

</div>

If your function is more expensive than summing floats then this will do the job.

(You said summing integers but your s = 0.0 is a float)

```julia
function func(R=5)
    s = Vector{Float64}(undef, R)
    Threads.@threads :static for i in 1:R
        s[i] = 1 # expensive 1
    end
    return sum(s)
end

```

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 21, 2022, 11:30am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/7 "2022-06-21T11:30:49Z")

</div>

I see `Folds.jl` is a generalisation of `ThreadsX.jl`, can I use multiprocessing and multithreads simultaneously?

---

<div class="post-metadata">

### Author: ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)
#### Post date: [June 21, 2022, 11:31am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/8 "2022-06-21T11:31:33Z")

</div>

Note though, that this can lead to [false sharing](https://en.wikipedia.org/wiki/False_sharing).

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 21, 2022, 11:46am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/9 "2022-06-21T11:46:20Z")

</div>

I find it strange that if I start julia with `-t auto`, getting 4 threads, I obtain the same result as with 1 thread, but if I set `-t 6` I get another result. What could be going on? how do I know that other results with auto would be correct?

---

<div class="post-metadata">

### Author: ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)
#### Post date: [June 21, 2022, 1:08pm UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/10 "2022-06-21T13:08:59Z")

</div>

This is a data race. It can happen with two threads as well!

Here is a possible scenario

```nohighlight
A: B:
read s read s
s++ s++
write s
                   write s

```

---

<div class="post-metadata">

### Author: ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)
#### Post date: [June 21, 2022, 9:12pm UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/11 "2022-06-21T21:12:41Z")

</div>

I suggest these changes to avoid races:

```julia
function func(R)
    b = [zero(paramvec) for _ in 1:Threads.nthreads()] # Don't use zeros(paramvec)
    Threads.@threads :static for i in 1:R
        sdata = datasimulator() # returns a vector of data
        b[Threads.threadid()] += estimatemodel(sdata) # returns a vector of parameters
    end
    bsum = sum(b)
    avgb = bsum ./ R # averages parameters across simulations
    return likelihood(avgb)
end

```

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [June 21, 2022, 10:19pm UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/12 "2022-06-21T22:19:41Z")

</div>

You are looking for something like Floops.jl, which hides a lot of the boilerplate. Another thing, you are missing a dot so you allocate on each iteration.

```julia
julia> using FLoops

julia> const test = rand(1000)

julia> function func(R)
           b = zero(rand(1000))
           for i in 1:R
              b .+= test # returns a vector of parameters
           end
           avgb = b ./ R # averages parameters across simulations
           return avgb
       end
func (generic function with 1 method)

julia> function func2(R)
           b = zero(rand(1000))
           @floop for i in 1:R
              @reduce b .+= test # returns a vector of parameters
           end
           avgb = b ./ R # averages parameters across simulations
           return avgb
       end
func2 (generic function with 1 method)

julia> @btime func(1000);
  129.000 μs (3 allocations: 23.81 KiB)

julia> @btime func2(1000);
  39.667 μs (35 allocations: 57.33 KiB)

```

---

<div class="post-metadata">

### Author: ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)
#### Post date: [June 22, 2022, 12:17am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/13 "2022-06-22T00:17:47Z")

</div>

> [@gbaraldi](#):
>
> `zero(rand(1000))`

Maybe there’s a more efficient way to do that. 😉

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 22, 2022, 12:40am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/14 "2022-06-22T00:40:36Z")

</div>

In summary, what’s best to use between `FLoops`, `Folds`, `ThreadsX`? in terms of ease of use, for a non-computer scientist? (is that a fair comparison?)

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [June 22, 2022, 2:36am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/15 "2022-06-22T02:36:46Z")

</div>

😂 I wanted to keep it as similar as the original 😉

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [June 22, 2022, 2:37am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/16 "2022-06-22T02:37:20Z")

</div>

Whatever you find easier to use is the best.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 22, 2022, 5:56am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/17 "2022-06-22T05:56:12Z")

</div>

If I want to make use of my university computer cluster, I suppose it would be better to use multi-processing, rather than threaded execution, no?

---

<div class="post-metadata">

### Author: ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)
#### Post date: [June 22, 2022, 5:58am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/18 "2022-06-22T05:58:23Z")

</div>

If you want to run a computation across multiple machines, then yes.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [June 22, 2022, 6:11am UTC](https://discourse.julialang.org/t/simple-example-of-threads/83049/19 "2022-06-22T06:11:06Z")

</div>

Ok, what’s the easiest way of doing that? Would this work?

1. In a file named multiproc.jl, write

```julia
using Distributed
using Folds

@everywhere include("main.jl")

```

where `main.jl` is the original file that I want to run (and which runs fine serially). That `main.jl` file calls other .jl files, including the one in which I perform the simulations in [my post above](https://discourse.julialang.org/t/simple-example-of-threads/83049/3), now modified to use `Folds` as follows:

```julia
function func(R, params)
        function sdatamodel(i)
            sdata = simulate_data()
        return auxiliarymodel(sdata)
    end

    avgb = Folds.mapreduce(sdatamodel, +, 1:R, DistributedEx(); init=zero(params)) ./ R
    return likelihood(avgb)
end

```

After that, I perform some other operations, like optimizing over some parameters which necessarily is a serial operation.  
2. Run `multiproc.jl` in the computer cluster with `julia -p 100 multiproc.jl`.
