Page MenuHome

Cause IMBuf to Respect Thread Count
Needs ReviewPublic

Authored by Karl Semich (fuzzyTew) on Dec 24 2017, 8:30 PM.

Details

Summary

IMBuf is initialized after argument parsing, so that it will honor the number of threads passed by the user. Previously this value was ignored.

When one thread is requested, threads are disabled in the library, so that libraries compiled with threading disabled may be used.

This makes it much easier to debug issues which occur during openexr image processing, as when threading is disabled the complete call stack is available.

Diff Detail

Repository
rB Blender

Event Timeline

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

This seems weird. If setGlobalThreadCount() sets count of additional threads to main, then it should also be num_threads - 1. Otherwise i do not see why you need to set OpenEXR threads to 0.

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

IlmThread treats 1 and 0 differently. If 1 thread is requested, it will spawn a new thread when a task is added. If 0 threads are requested, it will perform the work immediately when a task is added, in the same thread. Passing 0 allows blender to function with builds that have threading disabled.

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

Sorry! that was a draft; still understanding the interface.

What you say makes sense, but it would mean only 3 worker threads would be spawned if the user passed '-t 4' -- is this the correct behavior?

It is indeed the additional threads to main, but I think in the multithreaded situation main is just waiting on the worker threads. In the single threaded situation, disabling threading entirely (0: work performed in main thread) makes debugging much easier and allows the use of libraries that don't have threading support compiled in.

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

How many threads OpenEXR will actually use if you do`setGlobalThreadCount(4)` ? And is the main thread doing any jobs or it's just waiting?

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

It uses 5 threads; one main thread and 4 worker threads.

Each time the threaded task pool is used in OpenEXR it is a different block of code. To answer your question, I checked out the code for writing an exr file, which is where I had encountered a threaded crash that led me to make this patch.

In this block of code, when threading is enabled, the main thread does a small job of orchestrating adding new work to the queue as old tasks finish, but mostly is just waiting on a task to finish and only ever works when that happens. When threading is disabled, it does this in-between tasks.

It seems highly likely to me the main thread is only ever waiting inside OpenEXR, as the library has no run loop that I am aware of, but one would have to review the code paths to know for sure.

source/blender/imbuf/intern/openexr/openexr_api.cpp
1897

Thanks for investigation!

I'd say: add a comment above this line stating why we force 0 threads in the case Blender is using only one (basically, your explanation from the first reply) and the change will be good to go!

Karl Semich (fuzzyTew) edited the summary of this revision. (Show Details)

Explanatory comment for thread conditional.