# Multithreading - Backward incompatibilities

**URL:** https://discourse.itk.org/t/multithreading-backward-incompatibilities/977
**Category:** Uncategorized
**Created:** [June 4, 2018, 2:42pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977 "2018-06-04T14:42:52Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)
#### Post date: [June 4, 2018, 2:42pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/1 "2018-06-04T14:42:54Z")

</div>

Hi,  
I tried to compile the [RTK code](https://github.com/SimonRit/RTK) with ITK v5.0a02. You have made changes which seem to be backward incompatible, not only at compilation (e.g. [these errors](https://my.cdash.org/viewBuildError.php?buildid=1453362)), but also at execution (e.g., [this test](https://my.cdash.org/testDetails.php?test=39805500&build=1453270)).  
I assume this is intended as backward incompatible changes were planned to occur with the increment of ITK major version. Is there any documentation of the backward incompatible changes and how we should adapt our codes from ITK v4.13 to the coming ITK v5.0? That would be extremely useful.  
Thanks in advance,  
Simon

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [June 4, 2018, 9:15pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/2 "2018-06-04T21:15:17Z")

</div>

The migration guide can be found [here](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md). Description of `ITKV4_COMPATIBILITY` is currently missing from it, I will expand the document today/tomorrow. Please provide feedback about how useful it is, if there is anything missing etc.

Edit: `ITKV4_COMPATIBILITY` is already described. No need to update right now. Update will be needed after [this](http://review.source.kitware.com/#/c/23491/) patch branch is merged.

---

<div class="post-metadata">

### Author: ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)
#### Post date: [June 5, 2018, 6:11am UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/3 "2018-06-05T06:11:59Z")

</div>

Thanks, exactly what I was looking for. First question: what happens to filters that use threadId for something else than reporting? There is no other solution than disabling DynamicMultiThreading? For example, we use it to compute intermediate results per thread, see, e.g.,  
[https://github.com/SimonRit/RTK/blob/master/include/rtkTotalVariationImageFilter.hxx#L206](https://github.com/SimonRit/RTK/blob/master/include/rtkTotalVariationImageFilter.hxx#L206)

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [June 5, 2018, 11:31am UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/4 "2018-06-05T11:31:22Z")

</div>

There were about a dozen filters which used threadId to store intermediate results in an array. All those filters had DynamicMultiThreading disabled. Without re-writing the algorithm, there is no other solution.

Edit: in your case, you might get away with using [`atomic`](http://en.cppreference.com/w/cpp/atomic/atomic) m\_SumOfSquareRoots, and add to it directly, e.g.: `m_SumOfSquareRoots += sumOfSquareRoots;`

---

<div class="post-metadata">

### Author: ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)
#### Post date: [June 8, 2018, 11:57am UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/5 "2018-06-08T11:57:49Z")

</div>

Ok, thanks. I have tried to do it, other users can find my patch [here](https://github.com/SimonRit/RTK/commit/ae971ec64f39022d77f3d2aaadb33afff6de1a22) if they want a more complex example than the one you give on the [migration guide](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md). I think the document you pointed out lacks a reference to when renaming ThreadedGenerateData is not sufficient. This is clearly explained in [itkMultiThreader.h](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkMultiThreader.h).

I haven’t used your atomic suggestion, I guess I would have to do a proper performance test to check that it does not cost anything (which would be surprising to me, atomic additions are not costless on the GPU).

On a side note, I personally don’t understand the choice to have changed the default multi-threader, particularly since you have explicitly set dynamic multi-threading in ITK filters. You would have kept backward compatibility at not cost. But I’m sure I have missed important conversation on this topic, I should spend more time on discourse.

Thanks again for the help!

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [June 8, 2018, 1:23pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/6 "2018-06-08T13:23:36Z")

</div>

> [@simon.rit](#):
>
> … lacks a reference to when renaming ThreadedGenerateData is not sufficient. This is clearly explained in itkMultiThreader.h.

I created a [patch](http://review.source.kitware.com/#/c/23513/) which should address this. Please review.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [June 8, 2018, 1:25pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/7 "2018-06-08T13:25:57Z")

</div>

I didn’t notice that class was for GPU 😃

The default multi-threader has been changed for performance reasons. The `PlatformMultiThreader` has higher per-thread overhead, and always creating a new thread makes debugging/profiling difficult.

Also, having more work units than threads helps with load balancing in cases of unequal per-pixel work or the application sharing processor with other heavy computations (which possibly affects different threads unevenly).

---

<div class="post-metadata">

### Author: ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)
#### Post date: [June 8, 2018, 1:41pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/8 "2018-06-08T13:41:44Z")

</div>

It’s not for GPU, I wasn’t clear, sorry. I’m just saying that my only experience with atomic adds it’s on the gpu and it’s better to avoid them if you can to improve computation time. I don’t know if the same is true on the CPU.

Thanks for the explanation. I understand why you prefer using dynamic threading. But you would have had it without changing the default behavior since you have explicitely set DynamicThreadingOn in ITK filters.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [June 8, 2018, 1:48pm UTC](https://discourse.itk.org/t/multithreading-backward-incompatibilities/977/9 "2018-06-08T13:48:36Z")

</div>

Atomic operations might become a bottleneck if you are doing hundred thousand or more of them per second, and some memory address is contested a lot. For non-extreme scenarios it is probably cheaper to do a do few dozen atomic adds than to allocate, aggregate and free an array which holds intermediate data.

We changed the default so user code gets the better performance by default. Especially since opting out is relatively easy.
