# Threads.@threads scheduling puzzle

**URL:** <https://discourse.julialang.org/t/threads-threads-scheduling-puzzle/72831>\
**Category:** Performance\
**Tags:** parallel\
**Created:** [December 9, 2021, 3:11pm UTC](https://discourse.julialang.org/t/threads-threads-scheduling-puzzle/72831 "2021-12-09T15:11:37Z")\
**Posts on this page:** 3\
**Page:** 1

<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:** [December 9, 2021, 3:11pm UTC](https://discourse.julialang.org/t/threads-threads-scheduling-puzzle/72831/1 "2021-12-09T15:11:37Z")

</div>

Consider this

```julia
function test(duration)
  Threads.@threads for i=1:length(duration)
    sleep(duration[i])
  end
end

```

In my 2 core computer, 4 total threads with hyperthreading, running the above with

```julia
julia> @time test([2 1 1 1 2])
  3.005311 seconds (47 allocations: 2.625 KiB)

```

indicates that either the two `sleep(2)` are executed in the same “batch” or that, a thread that finished its `sleep(1)`, starts immediately a `sleep(2)` call.

However

```julia
julia> @time test([2 1 1 1 1])
  3.006186 seconds (47 allocations: 2.625 KiB)

```

contradicts the above. How are the loop iterations scheduled to the worker threads?

I use Julia `Version 1.7.0 (2021-11-30)` with `macOS 11.6.1` on a Dual-Core Intel Core i5.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 9, 2021, 3:24pm UTC](https://discourse.julialang.org/t/threads-threads-scheduling-puzzle/72831/2 "2021-12-09T15:24:28Z")

</div>

> [@pitsianis](#):
>
> How are the loop iterations scheduled to the worker threads?

I’ll copy the help from `@threads` since it is useful here:

```julia
help?> Threads.@threads
  Threads.@threads [schedule] for ... end

  A macro to parallelize a for loop to run with multiple threads. Splits the iteration space among multiple tasks and runs those
  tasks on threads according to a scheduling policy. A barrier is placed at the end of the loop which waits for all tasks to finish
  execution.

  The schedule argument can be used to request a particular scheduling policy. The only currently supported value is :static, which
  creates one task per thread and divides the iterations equally among them. Specifying :static is an error if used from inside
  another @threads loop or from a thread other than 1.

  The default schedule (used when no schedule argument is present) is subject to change.

```

So it is divided statically which each thread gets a chunk of the input array.

---

<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:** [December 9, 2021, 3:56pm UTC](https://discourse.julialang.org/t/threads-threads-scheduling-puzzle/72831/3 "2021-12-09T15:56:27Z")

</div>

Thank you for replying!

So among the four threads, the first thread is statically assigned loop iterations 1 and 2, and the rest of threads take one loop iteration each.

```julia
julia> @time test([2 1 1 1 1])
  3.010163 seconds (48 allocations: 2.922 KiB)

julia> @time test([1 2 1 1 1])
  3.007890 seconds (47 allocations: 2.625 KiB)

julia> @time test([1 1 2 1 1])
  2.017557 seconds (47 allocations: 2.625 KiB)

julia> @time test([1 1 1 2 1])
  2.005200 seconds (47 allocations: 2.625 KiB)

julia> @time test([1 1 1 1 2])
  2.017319 seconds (47 allocations: 2.625 KiB)

julia> @time test([1 1 2 2 2])
  2.012130 seconds (47 allocations: 2.625 KiB)

```
