# Profiling of Multi-threaded code

**URL:** <https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819>\
**Category:** General Usage\
**Created:** [December 9, 2016, 6:22am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819 "2016-12-09T06:22:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [December 9, 2016, 6:22am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/1 "2016-12-09T06:22:03Z")

</div>

Hello all,  
I would like to ask for any suggestions / recommendations about profiling multi-threaded code in Julia. The single-threaded version works fine, but once I turned on multi-threading, I hardly observe any improvement. From htop I see that most of the time threads do not do a useful computation.  
I have found this recent paper about profiling

> **[UM-CS-2015-008.pdf](https://web.cs.umass.edu/publication/docs/2015/UM-CS-2015-008.pdf)**
>
> 592.92 KB

but I am not sure, if that tool could be used.  
A related question is, would an intel vtune profiler help?  
Thank you in advance for answers.  
Tomas Pevny

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 9, 2016, 7:02am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/2 "2016-12-09T07:02:20Z")

</div>

A minimal working example would help. Lack of _any_ improvement could indicate that the threads are waiting for some common resource, or a result of a computation that is done in a single thread, but it is hard to say without seeing the code.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 9, 2016, 7:12am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/3 "2016-12-09T07:12:57Z")

</div>

Without knowing your code, it is impossible to know what’s going on. However, I do know that there’s a known issue which can occur. Have you checked to see if it’s due to an inference bug by using function barriers?

> <https://github.com/JuliaLang/julia/issues/17395>
>
> Consider the following code: 
> 
> \`\`\` julia
> using Base.Threads
> println("Number of t…hreads = $(nthreads())")
> x = rand(10^6)
> y = zeros(10^6)
> println("Warmup!")
> for i = 1:10^6
> y\[i\] = sin(x\[i\])^2 + cos(x\[i\])^2
> end
> t1 = @elapsed for i = 1:10^6
> y\[i\] = sin(x\[i\])^2 + cos(x\[i\])^2
> end
> @assert sum(y) == 10^6
> t2 = @elapsed @threads for i = 1:10^6
> y\[i\] = sin(x\[i\])^2 + cos(x\[i\])^2
> end
> @assert sum(y) == 10^6
> println("Serial time = $t1")
> println("Parallel time = $t2")
> \`\`\`
> 
> The output recorded on OSX is:
> 
> \`\`\`
> Number of threads = 4
> Warmup!
> Serial time = 0.239838418
> Parallel time = 0.282324893
> \`\`\`
> 
> The output recorded on Linux is: 
> 
> \`\`\`
> Number of threads = 4
> Warmup!
> Serial time = 0.227327406
> Parallel time = 0.542067206
> \`\`\`

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [December 9, 2016, 7:24am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/4 "2016-12-09T07:24:42Z")

</div>

Unfortunately, I cannot provide any simple working example, since it tries to parallelise calculation of a gradient of a Neural network, and I cannot publish nor the library, nor the data.  
Therefore I have been asking, if there would be a general way, how to find a bottleneck in the code. Something similar to the profiler available for a single-threaded applications.

I would be curious if Intel vTune amplifier would be of any help? I am sure that there is somewhere some bottleneck that just totally kills the parallelisation. Though, I do not know where.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 9, 2016, 7:37am UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/5 "2016-12-09T07:37:49Z")

</div>

Use `@code_warntype` first and see if there’s an inference problem. If so, you might be running into what I linked, or one of the issues linked from that issue. The workarounds are also given in that issue.

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [December 14, 2016, 2:44pm UTC](https://discourse.julialang.org/t/profiling-of-multi-threaded-code/819/6 "2016-12-14T14:44:13Z")

</div>

Hi,  
thanks for suggestions. I have tried code\_warntype and that has passed.  
I have been further playing with the threading and I have found that if set the number of threads used by openblas to one, then I see speed improvement. This seems to me that there was a problem with allocating threads on cores leading to overhead.  
So on the end, I have seen about two-fold improvement. What is weird is that as the algorithm progresses, I suddenly see a drop in the speed-up, i.e. the speed will get back to that of the single-thread case and even worse.  
On single-thread application, I do not see any issues like this, which makes this really hard to debug.
