# Control number of threads

**URL:** <https://discourse.julialang.org/t/control-number-of-threads/62887>\
**Category:** New to Julia\
**Tags:** question, parallel\
**Created:** [June 14, 2021, 12:36pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887 "2021-06-14T12:36:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [June 14, 2021, 12:36pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/1 "2021-06-14T12:36:55Z")

</div>

Hi,  
Let’s say i have started julia with `JULIA_NUM_THREADS=4`, however in one of my loop I only want to use 2 threads because it gives better performance. How do I do that so that `Threads.@threads` only use 2 threads?  
Thank you

---

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [June 15, 2021, 4:20pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/2 "2021-06-15T16:20:12Z")

</div>

Is there maybe any other libraries that give control over the number of threads that can be used? I looked at `Floops` but couldn’t find anything relevant to my problem.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [August 1, 2021, 5:43pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/3 "2021-08-01T17:43:22Z")

</div>

## Semaphore

You can use what ever threading solution you want. (Including `Threads.@threads` )  
plus a [`Base.Semaphore`](https://docs.julialang.org/en/v1/base/parallel/#Base.Semaphore) to control number of threads active at a time.

> **[Semaphore (programming)](https://en.wikipedia.org/wiki/Semaphore_(programming))**
>
> In computer science, a semaphore is a variable or abstract data type used to control access to a common resource by multiple threads and avoid critical section problems in a concurrent system such as a multitasking operating system. Semaphores are a type of synchronization primitive. A trivial semaphore is a plain variable that is changed (for example, incremented or decremented, or toggled) depending on programmer-defined conditions.
> A useful way to think of a semaphore as used in a real-world ...

Something like

```julia
using Threads
sem = Base.Semaphore(2) # at most 2 at a time
Threads.@threads for ii in 1:100
    Base.acquire(sem)
    println(threadid())
    Base.release(sem)
end

```

This will ensure only 2 threads are doing anything at a time.  
THough which two may change (and in the case of `Threads.@thread` will because of how it allocates work in advance).

It may not lead to optimal scheduling however.

### [ThreadPools.jl](https://github.com/tro3/ThreadPools.jl/tree/d6da10bad2ffeceb9ced75c0e151b29b9b256dbe)

ThreadPools exposes multiple different scheduling algorithms and they can take a pool argument of a subset of threads which you can construct in advance

```julia
using ThreadPools
pool = ThreadPools.StaticPool(3, 2) # use only 2 threads, starting from thread 3
@tthreads pool for ii in 1:100
    println(threadid())
end

```

This actually will ensure only thread #3 and #4 are used.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [August 1, 2021, 9:35pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/4 "2021-08-01T21:35:38Z")

</div>

For performance, a better way to limit tasks to be spawned is to specify the base case size rather than hard-coding the number of tasks. In JuliaFolds, you can specify this via `basesize` parameter in various APIs. This is especially true in library code.

This is a better approach since it works well even when the input size is changed. For an input smaller than `basesize`, you’d get a single-threaded program and with no `Task` spawn overhead. For a very large input, it’ll use additional CPUs as needed.

The `basesize` parameter can also be used to “simulate” different `JULIA_NUM_THREADS` without restarting Julia: [Frequently asked questions](https://juliafolds.github.io/data-parallelism/howto/faq/#can_i_change_the_number_of_execution_threads_without_restarting_julia)

---

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [August 2, 2021, 9:49am UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/5 "2021-08-02T09:49:17Z")

</div>

This is interesting but correct me if I am wrong, what you describe only works with already parallelised basic functions, @oxinabox solution is more general, correct?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [August 2, 2021, 2:38pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/6 "2021-08-02T14:38:37Z")

</div>

These “already parallelized basic functions” are just normal Julia functions. So, you can do the same for your hand-rolled function. For example, if you can rephrase your program as a [Divide-and-conquer algorithm](https://en.wikipedia.org/wiki/Divide-and-conquer_algorithm), it’s often straightforward to use this strategy. Even if this does not work, as I said in [Async limit - #3 by tkf](https://discourse.julialang.org/t/async-limit/62732/3), I’d recommend using the “worker pool” pattern rather than semaphore. For more specific comments, I think it’d be helpful if you can provide an MWE.

---

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [August 3, 2021, 12:17pm UTC](https://discourse.julialang.org/t/control-number-of-threads/62887/7 "2021-08-03T12:17:42Z")

</div>

@oxinabox thank you for your feedback, your answer is very good for me, hope you are ok that I chose @tkf answer.
