# Where does Julia (ecosystem) provide the greatest speedup, and where does it lag the most behind (compared to e.g. Python)?

**URL:** https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565
**Category:** Community
**Created:** [March 5, 2021, 3:22pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565 "2021-03-05T15:22:57Z")
**Posts on this page:** 5
**Page:** 3

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [March 9, 2021, 4:54pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565/42 "2021-03-09T16:54:43Z")

</div>

Right. At the moment if you want to get good scaling, you need to spawn tasks that have enough work to do to make it worth spawning them and split the work up in such a way that there’s enough parallelism to get all the work done faster in the end. Reducing spawn overhead makes that easier to accomplish. In the limit, if you can reduce spawn overhead to zero, you can make tasks that do tiny amounts of work and utilize all possible parallelism. Of course that’s not possible but you get the idea.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [March 9, 2021, 4:58pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565/43 "2021-03-09T16:58:30Z")

</div>

> [@StefanKarpinski](#):
>
> In the limit, if you can reduce spawn overhead to zero, you can make tasks that do tiny amounts of work and utilize all possible parallelism. Of course that’s not possible but you get the idea.

We expect nothing less!

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [March 9, 2021, 6:03pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565/44 "2021-03-09T18:03:45Z")

</div>

> [@dilumaluthge](#):
>
> For what it’s worth, if I recall correctly (@chriselrod correct me if I’m wrong) in Octavian the spawn overhead was most noticeable for small matrix sizes, where every nanosecond counts when you are trying to match the GFLOPS of OpenBLAS and MKL. For larger matrix sizes, it was less of an issue.

It’s also worth noting that as far as I’m aware, no other BLAS library is able to profitably turn on multithreading as early as Octavian is. Presumably the reason is that none of them have a multithreading system that has as low overhead as CheapThreads.jl

E.g. [https://github.com/JuliaLinearAlgebra/Octavian.jl/issues/24#issuecomment-766185684](https://github.com/JuliaLinearAlgebra/Octavian.jl/issues/24#issuecomment-766185684)

This might be an AMD tuning issue, I’d be interested to see a more up to date run on someone’s Intel CPU.

---

<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: [March 9, 2021, 8:47pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565/45 "2021-03-09T20:47:44Z")

</div>

> [@StefanKarpinski](#):
>
> Go’s superpower as a language seems to be the fact that they implemented an incredibly good built-in task-based threading system and absolutely everyone uses it.

Yes, I agree with this point and I think Go’s dev team has been making clever decisions _for the domain they are targeting_. But is this also a superpower in the domain Julia shines? Go has been criticised as a non-customizable language (e.g., took about a decade to get generics). Although Go developers effectively proved that customizability does not really matter in the domain Go is used for (e.g., networking applications), I think composability of Julia programs is deeply rooted in customizability (many custom array types, the broadcasting infrastructure, etc.).

I don’t think it’s entirely far-fetched to have some well-defined abstract protocol (but not _just_ coroutine; otherwise, yes, it’d then fracture the ecosystem) upon which the ecosystem is build while some performance engineers can tweak or build tailor-made (nested) runtimes. Although doing this for unrestricted concurrency is very challenging (which I still am interested in, though), if we restrict to just parallel computations, I think it’d be much easier and actually is very beneficial. In fact, I kind of have already done this in FoldsThreads.jl (ref: [ANN discourse thread](https://discourse.julialang.org/t/ann-foldsthreads-jl-a-zoo-of-pluggable-thread-based-data-parallel-execution-mechanisms/54662/6)) for a rather restricted kind of computation (= a slightly extended class of divide-and-conquer algorithmic skeleton). Each library API and even each _use_ of each API can have very different requirements in terms of the scheduling (e.g., some wants throughput, some wants low latency). So, I can’t help wondering if/how we can have a united ecosystem while maximizing the customizability of the scheduling. In a way, it’s a theme common to Halide/TVM/Tiramisu/MLIR.

> [@StefanKarpinski](#):
>
> Reducing spawn overhead makes that easier to accomplish. In the limit, if you can reduce spawn overhead to zero, you can make tasks that do tiny amounts of work and utilize all possible parallelism. Of course that’s not possible but you get the idea.

Isn’t “that’s not possible” actually the point? I think more realistic and beneficial approach is to make parallel tasks _fusible_ by the compiler, runtime, and libraries. It’d let programmers denote existing parallelism in the program without causing incurring the run-time cost. Decoupling how and what enables more optimizations by the compiler, runtime, and engineers. Exploiting the parallelism or not in actual compiled result can be lazily decided at much later stages. An alternative notion of task for [may-happen in parallel parallelism (JuliaLang/julia#39773)](https://github.com/JuliaLang/julia/pull/39773) (Cilk-like tasks) is a prerequisite for this (and other optimizations). This is because we can’t fuse tasks if they try to use unrestricted concurrent communication APIs without potentially introducing deadlocks.

---

<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: [March 10, 2021, 9:43pm UTC](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565/46 "2021-03-10T21:43:41Z")

</div>

> [@tkf](#):
>
> Isn’t “that’s not possible” actually the point?

Actually, I said too much 🙂 Obviously, it’s better to make the scheduler as fast as possible. I wanted to bring up that there are multiple mostly orthogonal aspects that we can improve Julia’s thread-based parallelism.

[Previous page](https://discourse.julialang.org/t/where-does-julia-ecosystem-provide-the-greatest-speedup-and-where-does-it-lag-the-most-behind-compared-to-e-g-python/56565.md?page=2)
