Skip to content

Conversation

@pmolodo
Copy link
Contributor

@pmolodo pmolodo commented Oct 21, 2024

Important

This is a duplicate of this PR:

...except pulled out of the UsdLux-HdEmbree PR "chain", to make for easier standalone integration, as it has no other PR dependencies, and is a simple/small change.

I will close this PR if the other is merged first, and vice-versa.

Description of Change(s)

Fixes an issue where pre-oneTBB, threads spawned from the non-root thread (such as the render thread) would not respect PXR_WORK_THREAD_LIMIT

Fixes Issue(s)

  • renderThread-spawned processes don't respect PXR_WORK_THREAD_LIMIT
  • I have verified that all unit tests pass with the proposed changes
  • I have submitted a signed Contributor License Agreement

@jesschimein
Copy link
Collaborator

Filed as internal issue #USD-10340

@jesschimein
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@pmolodo pmolodo force-pushed the pr/hdEmbree-respect-PXR_WORK_THREAD_LIMIT-standalone branch from 57a4e85 to 5a818ce Compare October 22, 2024 18:13
@pmolodo pmolodo force-pushed the pr/hdEmbree-respect-PXR_WORK_THREAD_LIMIT-standalone branch from 5a818ce to 32d1f06 Compare October 23, 2024 18:19
@pmolodo
Copy link
Contributor Author

pmolodo commented Oct 23, 2024

Updated to not modify the API of the work library

@pmolodo pmolodo force-pushed the pr/hdEmbree-respect-PXR_WORK_THREAD_LIMIT-standalone branch from 32d1f06 to 98f79a8 Compare January 28, 2025 22:31
@pmolodo pmolodo force-pushed the pr/hdEmbree-respect-PXR_WORK_THREAD_LIMIT-standalone branch from 98f79a8 to a6d8610 Compare February 5, 2025 17:28
@jesschimein
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tcauchois
Copy link
Contributor

Hey Paul, just to clarify: the root issue here is that we're spawning TBB threads from the hydra render thread, which does not have a tbb::task_scheduler_init because libWork only constructs one on the main thread at static initialization time? Is that roughly correct? I'm not sure having it be scoped is quite right; the render thread is long lived and we should be able to just initialize one the first time we get into the callback and keep it around. I don't have a sense of how heavy they are to construct, though.

We will likely need to tweak this slightly to make it oneTBB-safe; I can provide suggestions on github, or just fix it up inline as I pull it down; let me know.

@pmolodo
Copy link
Contributor Author

pmolodo commented May 15, 2025

We will likely need to tweak this slightly to make it oneTBB-safe

Things already work with oneTBB - it handles the thread limits in a different / better / more global way (though I no longer recall the exact details at this moment - can find it if you want, though).

This PR should be #if guarded to only change things for "old" TBB.

Hey Paul, just to clarify: the root issue here is that we're spawning TBB threads from the hydra render thread, which does not have a tbb::task_scheduler_init because libWork only constructs one on the main thread at static initialization time? Is that roughly correct? I'm not sure having it be scoped is quite right; the render thread is long lived and we should be able to just initialize one the first time we get into the callback and keep it around. I don't have a sense of how heavy they are to construct, though.

Yeah, it's been a minute since I wrote this / investigated, but that sounds about right. And absolutely, I think the "correct" thing to do would be to fix this in a more general way at a higher level - ie, libwork. However, since this issue only affects "old" TBB (things already work nicely in oneTBB), and I was a bit leery of making changes to libwork (other than the documentation-only commit I added), I figured I'd just make my tweaks to hdEmbree.

If you want to fix it "right" at a higher level, though, go for it!

I can provide suggestions on github, or just fix it up inline as I pull it down; let me know.

Fixing inline as you go is fine with me!

Copy link
Contributor

@tcauchois tcauchois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things that came up in internal review of this.

Let me know (1) what you think of the changes; and (2) whether I should check the modified version in and then send you a commit link, or bring it back to github as suggestions for you to apply to the PR or what.

// change API of work lib. Will go away once we don't need to support tbb < 12
// (ie, pre-OneTBB)
static unsigned
HdEmbree_GetConcurrencyLimitSetting()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I have consensus internally to move this function back into "work". If I make that change, do you want me to post it here for review or just check it in?

auto limit = HdEmbree_GetConcurrencyLimitSetting();
if (limit != 0) {
_tbbTaskSchedInit =
std::make_unique<tbb::task_scheduler_init>(limit);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wanted to find a way to jam this back into "work", but we're also simultaneously abstracting "work" to be able to use oneTBB as well as non-TBB threadpools, and there weren't any API contracts we felt good about adding. So I think keeping the tbb::task_scheduler_init here is the lesser of two evils; the only negative side effect it has is creating a hard dependency on TBB, which is fine for a few years I think.

I don't think the task_scheduler_init can be scoped like you're doing here, but to give it the lifetime of the thread we'd need to either add it to HdRenderThread directly or subclass HdRenderThread, which seems like too much work, so I'm fine with leaving this as-is.


// Render by scheduling square tiles of the sample buffer in a parallel
// for loop.
#if TBB_INTERFACE_VERSION_MAJOR < 12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about scoping; anyway, at the least this should probably move to the top of the function. I've done this internally but can post it back if you'd like.

#include <thread>

// -------------------------------------------------------------------------
// Old TBB workaround - can remove once OneTBB is mandatory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Old TBB workaround - can remove once OneTBB is mandatory
// Old TBB workaround - we plan to remove this once OpenUSD adopts
// oneTBB as a min spec. Note: for non-TBB-based work implementations,
// this code shouldn't cause any trouble.

@pmolodo pmolodo force-pushed the pr/hdEmbree-respect-PXR_WORK_THREAD_LIMIT-standalone branch from a6d8610 to 112039b Compare June 11, 2025 22:22
@pixar-oss pixar-oss closed this in 5615302 Jun 12, 2025
meshula pushed a commit to meshula/USD that referenced this pull request Sep 11, 2025
Fixes an issue where pre-oneTBB, threads spawned from the non-root thread (such as the render thread) would not respect PXR_WORK_THREAD_LIMIT. WorkGetConcurrencyLimitSetting is now exported from libwork, and for old TBB versions we create an appropriate task_scheduler_init from the render thread.

- renderThread-spawned processes don't respect PXR_WORK_THREAD_LIMIT

Closes PixarAnimationStudios#3198
Closes PixarAnimationStudios#3370

(Internal change: 2369113)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants