Skip to content

Commit 532053e

Browse files
authored
perf: Share Shading Context when optimizing/jitting a shader (#1952)
Share Shading Context when optimizing/jitting a shader vs. grabbing an additional context. No need for a 2nd set of heaps/buffers when the existing context can be reused. Reduces memory footprint which increases cache efficiency, especially for threaded usage. We can just swap the TexturePerThread info out for a null pointer and restore the previous one afterwards For completeness we also process the errors in the context. Signed-off-by: Alex M. Wells <alex.m.wells@intel.com>
1 parent 67693b9 commit 532053e

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

src/liboslexec/context.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,25 @@ ShadingContext::~ShadingContext()
6868
free_dict_resources();
6969
}
7070

71+
ShadingContext::RestoreState
72+
ShadingContext::repurposeForJit()
73+
{
74+
process_errors();
75+
// Match previous behavior of nullptr value for texture thread info
76+
// as if we created a new ShadingContext
77+
RestoreState restore_state { texture_thread_info() };
78+
texture_thread_info(nullptr);
79+
return restore_state;
80+
}
81+
82+
// Process any errors from JIT and restore the texture_thread_info
83+
void
84+
ShadingContext::restoreFromJit(const RestoreState& restore_state)
85+
{
86+
// Restore "this" ShadingContext for execution
87+
process_errors();
88+
texture_thread_info(restore_state.m_pre_jit_texture_thread_info);
89+
}
7190

7291

7392
bool
@@ -86,14 +105,14 @@ ShadingContext::execute_init(ShaderGroup& sgroup, int threadindex,
86105
if (sgroup.nlayers()) {
87106
sgroup.start_running();
88107
if (!sgroup.jitted()) {
89-
auto ctx = shadingsys().get_context(thread_info());
90-
shadingsys().optimize_group(sgroup, ctx, true /*do_jit*/);
108+
auto restore_state = repurposeForJit();
109+
shadingsys().optimize_group(sgroup, this, true /*do_jit*/);
91110
if (shadingsys().m_greedyjit
92111
&& shadingsys().m_groups_to_compile_count) {
93112
// If we are greedily JITing, optimize/JIT everything now
94113
shadingsys().optimize_all_groups();
95114
}
96-
shadingsys().release_context(ctx);
115+
restoreFromJit(restore_state);
97116
}
98117
if (sgroup.does_nothing())
99118
return false;
@@ -260,19 +279,16 @@ ShadingContext::Batched<WidthT>::execute_init(
260279
if (sgroup.nlayers()) {
261280
sgroup.start_running();
262281
if (!sgroup.batch_jitted()) {
263-
// Matching ShadingContext::execute_init behavior
264-
// of grabbing another context.
265-
// TODO: Is this necessary, why can't we just use the
266-
// the existing context()?
267-
//shadingsys().template batched<WidthT>().jit_group(sgroup, &context());
268-
auto ctx = shadingsys().get_context(context().thread_info());
269-
shadingsys().template batched<WidthT>().jit_group(sgroup, ctx);
282+
auto restore_state = context().repurposeForJit();
283+
shadingsys().template batched<WidthT>().jit_group(sgroup,
284+
&context());
285+
270286
if (shadingsys().m_greedyjit
271287
&& shadingsys().m_groups_to_compile_count) {
272288
// If we are greedily JITing, optimize/JIT everything now
273289
shadingsys().template batched<WidthT>().jit_all_groups();
274290
}
275-
shadingsys().release_context(ctx);
291+
context().restoreFromJit(restore_state);
276292
}
277293
// To handle layers that were not used but still possibly had
278294
// render outputs, we always generate a run function even for

src/liboslexec/oslexec_pvt.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,6 +2518,18 @@ class OSLEXECPUBLIC ShadingContext {
25182518
// wide data offsets should be used
25192519
int batch_size_executed;
25202520
bool execution_is_batched() const { return batch_size_executed != 0; }
2521+
2522+
2523+
struct RestoreState {
2524+
TextureSystem::Perthread* m_pre_jit_texture_thread_info;
2525+
};
2526+
2527+
// Rather than allocate an additional ShadingContext for JIT
2528+
// reuse this one by processing any existing errors
2529+
// and saving off any necessary state to be restored afterwards
2530+
RestoreState repurposeForJit();
2531+
// Process any errors from JIT and restore the state
2532+
void restoreFromJit(const RestoreState&);
25212533
};
25222534

25232535

0 commit comments

Comments
 (0)