# How to guarantee that using @Threads/@tspawnat will create threads that work on different Cores?

**URL:** <https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280>\
**Category:** General Usage\
**Tags:** question\
**Created:** [February 27, 2023, 3:59pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280 "2023-02-27T15:59:42Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 3:59pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/1 "2023-02-27T15:59:42Z")

</div>

- I am defining `julia -t 2` before running my julia code which contains `@Threads/@tspawnat` to let some works run on the two threads. However, these two threads could be ruining on the same core and I am wondering if there is a way in julia to let the code works on a core not only thread.  
I tried to run julia with `julia -p 2 -t 2` and not sure if this can solve what I want.
- As I know `threadid()` can check the id of the working thread. And `myid()` can check the id of the working core, right?

---

<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:** [February 27, 2023, 4:08pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/2 "2023-02-27T16:08:33Z")

</div>

The easiest option is to set the environment variable [`JULIA_EXCLUSIVE=1`](https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_EXCLUSIVE). If you want more explicit control (and if you’re on linux) you can use [ThreadPinning.jl](https://github.com/carstenbauer/ThreadPinning.jl).

---

<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:** [February 27, 2023, 4:11pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/3 "2023-02-27T16:11:05Z")

</div>

Note that the `-p` option (and also `myid()`) is for multiprocessing (while `-t` is for multithreading) I would assume that you don’t want to mix both parallelisation variants. Hence, you should drop the `-p 2` part.

---

<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:** [February 27, 2023, 4:12pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/4 "2023-02-27T16:12:03Z")

</div>

> [@Amro](#):
>
> And `myid()` can check the id of the working core, right?

No. It indicates the id of a worker process (when using multiprocessing).

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:12pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/5 "2023-02-27T16:12:31Z")

</div>

> [@carstenbauer](#):
>
> JULIA\_EXCLUSIVE=1

- Could you please tell me how to set `JULIA_EXCLUSIVE=1` if I am using VS Code?
- I am working on windows, does `ThreadPinning.jl.` only work in linux?

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:14pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/6 "2023-02-27T16:14:47Z")

</div>

> [@carstenbauer](#):
>
> No. It indicates the id of a worker process (when using multiprocessing).

- what is function in julia to know the core id?
- It seems that I dont know the difference between `threads`, `processes` and `cores`. Could you please give me a bit explanatins?

---

<div class="post-metadata">

**Author:** ![LeePhillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leephillips/32/205514_2.png) [@LeePhillips](https://discourse.julialang.org/u/LeePhillips)\
**Post date:** [February 27, 2023, 4:15pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/7 "2023-02-27T16:15:16Z")

</div>

As Carsten Bauer says. Also, myid() gets you the process number, nothing about what core it’s running on. Without setting any environment variables, Julia will let the operating system schedule the threads, which will generally do what you want. Just run a job and watch your CPU meters, and you’ll see that the OS is using the available cores.

---

<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:** [February 27, 2023, 4:15pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/8 "2023-02-27T16:15:30Z")

</div>

> [@Amro](#):
>
> Could you please tell me how to set `JULIA_EXCLUSIVE=1` if I am using VS Code?

I assume you want to use the integrated REPL from the Julia VSCode extension? In this case, I’m not sure but would assume that putting `JULIA_EXCLUSIVE=1 julia` under the `Julia.executable` setting (or similar) should work.

Alternatively, should can set the environment variable globally. Should be straightforward to google.

> [@Amro](#):
>
> I am working on windows, does `ThreadPinning.jl.` only work in linux?

Currently yes. There is a rudimentary PR for Windows support but it’s pretty stale.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:17pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/9 "2023-02-27T16:17:41Z")

</div>

> [@carstenbauer](#):
>
> I assume you want to use the integrated REPL from the Julia VSCode extension? In this case, I’m not sure but would assume that putting `JULIA_EXCLUSIVE=1 julia` under the `Julia.executable` setting (or similar) should work.

- Yes.
- So, if I want to run julia from command window, I should write `julia -t 2 JULIA_EXCLUSIVE=1` which gives error?

---

<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:** [February 27, 2023, 4:18pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/10 "2023-02-27T16:18:35Z")

</div>

> [@Amro](#):
>
> So, if I want to run julia from command window, I should write `julia -t 2 JULIA_EXCLUSIVE=1` which gives error?

The other way around: `JULIA_EXCLUSIVE=1 julia -t 2`

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:19pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/11 "2023-02-27T16:19:32Z")

</div>

> [@carstenbauer](#):
>
> The other way around: `JULIA_EXCLUSIVE=1 julia -t 2`

Writing that gave me:

```julia
JULIA_EXCLUSIVE=1 : The term 'JULIA_EXCLUSIVE=1' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1
+ JULIA_EXCLUSIVE=1 julia -t 2
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (JULIA_EXCLUSIVE=1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

```

---

<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:** [February 27, 2023, 4:21pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/12 "2023-02-27T16:21:37Z")

</div>

Hm, ok, maybe this only works on Linux. In any case, it should be easy to google how to set environment variables on Windows. I think you can do it in two steps

```julia
set JULIA_EXCLUSIVE=1
julia -t 2

```

But it’s been a while since I’ve last touched a Windows machine. So I’m not the best person to help you further.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:24pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/13 "2023-02-27T16:24:35Z")

</div>

> [@carstenbauer](#):
>
> ```julia
> set JULIA_EXCLUSIVE=1
> julia -t 2
> 
> ```

Thank you!  
I wrote that and I did not get errors. So, if I want to double check that the `JULIA_EXCLUSIVE=1` is set correctly, what is the command/function that I have to put in Julia REPL? I put in the REPL

```julia
julia> ENV["JULIA_EXCLUSIVE"]
ERROR: KeyError: key "JULIA_EXCLUSIVE" not found`

```

---

<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:** [February 27, 2023, 4:30pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/14 "2023-02-27T16:30:46Z")

</div>

There is no built-in function for this (AFAIR) but you can define

```julia
const kernel32 = "kernel32"
get_current_processor_number() = @ccall kernel32.GetCurrentProcessorNumber()::Culong

```

Calling this function on the threads (e.g. with `@tspawnat`) should give you the desired processor id.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:39pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/15 "2023-02-27T16:39:13Z")

</div>

> [@carstenbauer](#):
>
> Calling this function on the threads (e.g. with `@tspawnat`) should give you the desired processor id.

I wrote the below test MWE, however, I got error. Is the location of `const kernel32 = "kernel32"` wrong?

```julia
function f()
  const kernel32 = "kernel32"
          thrs = [@tspawnat i begin
                  println("Thread $(threadid()) ")
                  get_current_processor_number() = @ccall kernel32.GetCurrentProcessorNumber()::Culong
          end for i = 2:nthreads()];

          # Main Thread
          println("Thread $(threadid()) ")
          get_current_processor_number() = @ccall kernel32.GetCurrentProcessorNumber()::Culong
  fetch.(thrs);
  return nothing
end
f()
ERROR: LoadError: syntax: unsupported `const` declaration on local variable around C:\pathtofile\tt.jl

```

---

<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:** [February 27, 2023, 4:45pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/16 "2023-02-27T16:45:03Z")

</div>

This should do it (written it down without testing it):

```julia
const kernel32 = "kernel32"
get_current_processor_number() = @ccall kernel32.GetCurrentProcessorNumber()::Culong

Threads.@threads :static for i in 1:Threads.nthreads()
    procid = get_current_processor_number()
    println("Thread: $i, Processor: $procid")
end

```

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 4:53pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/17 "2023-02-27T16:53:01Z")

</div>

> [@carstenbauer](#):
>
> This should do it (written it down without testing it):

Thank you very much!  
I followed and I got

```julia
Thread: 1, Processor: 5
Thread: 2, Processor: 7

```

However, my computer has only 6 physical cores as shown below. And I am wondering why I got `proccessor: 7`

```julia
julia> versioninfo()
Julia Version 1.8.5
Commit 17cfb8e65e (2023-01-08 06:45 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 12 × Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
  Threads: 2 on 12 virtual cores

```

Moreover, I run julia without setting `JULIA_EXCLUSIVE=1` and then run your code and I got similar results such as below. So, I did not realize the difference.

```julia
Thread: 2, Processor: 9
Thread: 1, Processor: 5

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 27, 2023, 5:34pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/18 "2023-02-27T17:34:36Z")

</div>

Do you happen to have multiple processors in your system? Also does your system have hyperthreading?

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [February 27, 2023, 6:21pm UTC](https://discourse.julialang.org/t/how-to-guarantee-that-using-threads-tspawnat-will-create-threads-that-work-on-different-cores/95280/19 "2023-02-27T18:21:25Z")

</div>

> [@mkitti](#):
>
> Do you happen to have multiple processors in your system? Also does your system have hyperthreading?

Yes and I can see the multiple CPUs (12) in the `Task Manager` and when I write `versioninfo()` it gives:

```julia
Julia Version 1.8.5
Commit 17cfb8e65e (2023-01-08 06:45 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 12 × Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
  Threads: 2 on 12 virtual cores

```
