Skip to content

Commit

Permalink
[hdEmbree] ensure we respect PXR_WORK_THREAD_LIMIT
Browse files Browse the repository at this point in the history
  • Loading branch information
pmolodo committed Oct 22, 2024
1 parent 12ec28c commit 5a818ce
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions pxr/imaging/plugin/hdEmbree/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,77 @@
#include <chrono>
#include <thread>

// -------------------------------------------------------------------------
// Old TBB workaround - can remove once OneTBB is mandatory
// -------------------------------------------------------------------------
#include <tbb/tbb_stddef.h>

#if TBB_INTERFACE_VERSION_MAJOR < 12

#include <memory>

#include <tbb/task_scheduler_init.h>

PXR_NAMESPACE_OPEN_SCOPE

extern TfEnvSetting<int> PXR_WORK_THREAD_LIMIT;

PXR_NAMESPACE_CLOSE_SCOPE

namespace {

PXR_NAMESPACE_USING_DIRECTIVE

// This function always returns either 0 (meaning "no change") or >= 1
//
// Duplication of code from threadLimits.cpp - copied here to avoid having to
// change API of work lib. Will go away once we don't need to support tbb < 12
// (ie, pre-OneTBB)
static unsigned
HdEmbree_NormalizeThreadCount(const int n)
{
// Zero means "no change", and n >= 1 means exactly n threads, so simply
// pass those values through unchanged.
// For negative integers, subtract the absolute value from the total number
// of available cores (denoting all but n cores). If |n| >= number of cores,
// clamp to 1 to set single-threaded mode.
return n >= 0 ? n : std::max<int>(1, n + WorkGetPhysicalConcurrencyLimit());
}


// Returns the normalized thread limit value from the environment setting. Note
// that 0 means "no change", i.e. the environment setting does not apply.
//
// Duplication of code from threadLimits.cpp - copied here to avoid having to
// change API of work lib. Will go away once we don't need to support tbb < 12
// (ie, pre-OneTBB)
static unsigned
HdEmbree_GetConcurrencyLimitSetting()
{
return HdEmbree_NormalizeThreadCount(TfGetEnvSetting(PXR_WORK_THREAD_LIMIT));
}


// Make the calling context respect PXR_WORK_THREAD_LIMIT, if run from a thread
// other than the main thread (ie, the renderThread)
class _ScopedThreadScheduler {
public:
_ScopedThreadScheduler() {
auto limit = HdEmbree_GetConcurrencyLimitSetting();
if (limit != 0) {
_tbbTaskSchedInit =
std::make_unique<tbb::task_scheduler_init>(limit);
}
}

std::unique_ptr<tbb::task_scheduler_init> _tbbTaskSchedInit;
};

} // anonymous namespace

#endif // TBB_INTERFACE_VERSION_MAJOR < 12


namespace {

PXR_NAMESPACE_USING_DIRECTIVE
Expand Down Expand Up @@ -453,6 +524,9 @@ HdEmbreeRenderer::Render(HdRenderThread *renderThread)

// Render by scheduling square tiles of the sample buffer in a parallel
// for loop.
#if TBB_INTERFACE_VERSION_MAJOR < 12
_ScopedThreadScheduler scheduler;
#endif
// Always pass the renderThread to _RenderTiles to allow the first frame
// to be interrupted.
WorkParallelForN(numTilesX*numTilesY,
Expand Down

0 comments on commit 5a818ce

Please sign in to comment.