# Big performance slowdown increasing Julia threads but keeping parallelism the same?

**URL:** <https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385>\
**Category:** General Usage\
**Created:** [January 2, 2025, 7:30pm UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385 "2025-01-02T19:30:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [January 2, 2025, 7:30pm UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385/1 "2025-01-02T19:30:52Z")

</div>

I have some code for processing files in parallel like so (simplified):

```julia
function process_files_parallel(paths, n_parallel = 12)
    # create to-do list
    todo_channel = Channel{eltype(paths)}(length(paths))
    for p in paths
        put!(todo_channel, p)
    end
    close(todo_channel)
    # spawn worker tasks
    tasks = map(1:n_parallel) do i
        Threads.@spawn begin
            for path in todo_channel
                do_something(path)
            end
        end
    end
    # wait for all worker tasks to conclude, meaning we processed all files
    wait.(tasks)
end

```

On a 16 core EC2 machine, timings for `process_files_parallel(lst_of_36_paths, 6)` (ie 6 worker tasks):

- If I run Julia (via the VSCode REPL, so including Revise etc) with `"julia.NumThreads" : 6` =\> 36 seconds
- `"julia.NumThreads" : 16` =\> 70 seconds

I understand [some] reasons why running too many _workers_ in parallel can lead to slowdowns: thrashing the CPU, worse cache locality, high context switching costs, etc. But why does increasing the number of threads available to Julia with the same number of workers produce a big slowdown? Can’t the extra threads just…do nothing? Is Julia spending tons of compute cycles juggling the 6 worker tasks between 16 threads?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [January 3, 2025, 12:08am UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385/2 "2025-01-03T00:08:57Z")

</div>

I have to admit that I do not understand your code. Just some general remarks:

- more threads means higher pressure on the garbage collector; make sure to benchmark this effect and check the percentage of time used by the GC
- more threads put more pressure on the CPU cache

---

<div class="post-metadata">

**Author:** ![Christian\_Rorvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christian_rorvik/32/965_2.png) [@Christian\_Rorvik](https://discourse.julialang.org/u/Christian_Rorvik)\
**Post date:** [January 3, 2025, 8:38am UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385/3 "2025-01-03T08:38:53Z")

</div>

You may be hitting lock and channel scalability issues, where threads are woken up too aggressively. There’s been some recent changes to locks, but nothing yet to fix the channel behavior: [ReentrantLock: wakeup a single task on unlock and add a short spin by andrebsguedes · Pull Request #56814 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/56814)

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [January 3, 2025, 10:05am UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385/4 "2025-01-03T10:05:09Z")

</div>

> [@Christian\_Rorvik](#):
>
> You may be hitting lock and channel scalability issues, where threads are woken up too aggressively. There’s been some recent changes to locks, but nothing yet to fix the channel behavior:

If using a Channel is causing issue, perhaps try accessing the paths via an index wrapped in [`Threads.Atomic`](https://docs.julialang.org/en/v1/manual/multi-threading/#man-atomic-operations)

> **Code Outline**
>
> ```julia
> function process_files_parallel2(paths, n_parallel = 12)
> # create to-do list
> todo_vector = collect(paths)
> path_index = Threads.Atomic{Int}(1)
> 
> # spawn worker tasks
> @sync for t in 1:n_parallel
> Threads.@spawn begin
> while true
> i = atomic_add!(path_index, 1)
> if i in eachindex(todo_vector)
> do_something(todo_vector[i])
> else
> break
> end
> end
> end
> end
> end
> 
> ```

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [January 3, 2025, 1:19pm UTC](https://discourse.julialang.org/t/big-performance-slowdown-increasing-julia-threads-but-keeping-parallelism-the-same/124385/5 "2025-01-03T13:19:30Z")

</div>

It’s a bit difficult to trace the problem without a running example.

However, I’ve had a similar issue, though not entirely the same, some time ago concerning scheduling of tasks. My issue was with a constant number of threads, but with varying number of tasks. Task scheduling also depends on the number of threads, so it could be related. It’s in [Task scheduling regression · Issue #54101 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/54101).

Have you tried your example with julia 1.10.7 and with the nightly version?
