-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cache System Tracing Spans #9390
Changes from all commits
32ac77d
cabaece
987b987
c6fdcb9
2859b4d
5abf79e
79484d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ use bevy_tasks::{ComputeTaskPool, Scope, TaskPool, ThreadExecutor}; | |
use bevy_utils::default; | ||
use bevy_utils::syncunsafecell::SyncUnsafeCell; | ||
#[cfg(feature = "trace")] | ||
use bevy_utils::tracing::{info_span, Instrument}; | ||
use bevy_utils::tracing::{info_span, Instrument, Span}; | ||
use std::panic::AssertUnwindSafe; | ||
|
||
use async_channel::{Receiver, Sender}; | ||
|
@@ -62,6 +62,9 @@ struct SystemTaskMetadata { | |
is_send: bool, | ||
/// Is `true` if the system is exclusive. | ||
is_exclusive: bool, | ||
/// Cached tracing span for system task | ||
#[cfg(feature = "trace")] | ||
system_task_span: Span, | ||
} | ||
|
||
/// The result of running a system that is sent across a channel. | ||
|
@@ -153,6 +156,11 @@ impl SystemExecutor for MultiThreadedExecutor { | |
dependents: schedule.system_dependents[index].clone(), | ||
is_send: schedule.systems[index].is_send(), | ||
is_exclusive: schedule.systems[index].is_exclusive(), | ||
#[cfg(feature = "trace")] | ||
system_task_span: info_span!( | ||
"system_task", | ||
name = &*schedule.systems[index].name() | ||
), | ||
}); | ||
} | ||
|
||
|
@@ -486,26 +494,16 @@ impl MultiThreadedExecutor { | |
) { | ||
// SAFETY: this system is not running, no other reference exists | ||
let system = unsafe { &mut *systems[system_index].get() }; | ||
|
||
#[cfg(feature = "trace")] | ||
let task_span = info_span!("system_task", name = &*system.name()); | ||
#[cfg(feature = "trace")] | ||
let system_span = info_span!("system", name = &*system.name()); | ||
|
||
let sender = self.sender.clone(); | ||
let panic_payload = self.panic_payload.clone(); | ||
let task = async move { | ||
#[cfg(feature = "trace")] | ||
let system_guard = system_span.enter(); | ||
let res = std::panic::catch_unwind(AssertUnwindSafe(|| { | ||
// SAFETY: | ||
// - The caller ensures that we have permission to | ||
// access the world data used by the system. | ||
// - `update_archetype_component_access` has been called. | ||
unsafe { system.run_unsafe((), world) }; | ||
})); | ||
#[cfg(feature = "trace")] | ||
drop(system_guard); | ||
// tell the executor that the system finished | ||
sender | ||
.try_send(SystemResult { | ||
|
@@ -524,7 +522,11 @@ impl MultiThreadedExecutor { | |
}; | ||
|
||
#[cfg(feature = "trace")] | ||
let task = task.instrument(task_span); | ||
let task = task.instrument( | ||
self.system_task_metadata[system_index] | ||
.system_task_span | ||
.clone(), | ||
); | ||
Comment on lines
+525
to
+529
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The instrumentation here does help measure the additional scheduler overhead, which is thankfully very low right now. However, I do see how this both adds even more profiling overhead and how it might not be all that useful to the typical user. Not sure how to best approach toggling this on or off though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My worry is that the time needed for the instrumentation itself here may be in the same order of magniture as the one it is measuring (in addition to the one already measured inside the |
||
|
||
let system_meta = &self.system_task_metadata[system_index]; | ||
self.active_access | ||
|
@@ -550,23 +552,14 @@ impl MultiThreadedExecutor { | |
// SAFETY: this system is not running, no other reference exists | ||
let system = unsafe { &mut *systems[system_index].get() }; | ||
|
||
#[cfg(feature = "trace")] | ||
let task_span = info_span!("system_task", name = &*system.name()); | ||
#[cfg(feature = "trace")] | ||
let system_span = info_span!("system", name = &*system.name()); | ||
|
||
let sender = self.sender.clone(); | ||
let panic_payload = self.panic_payload.clone(); | ||
if is_apply_deferred(system) { | ||
// TODO: avoid allocation | ||
let unapplied_systems = self.unapplied_systems.clone(); | ||
self.unapplied_systems.clear(); | ||
let task = async move { | ||
#[cfg(feature = "trace")] | ||
let system_guard = system_span.enter(); | ||
let res = apply_deferred(&unapplied_systems, systems, world); | ||
#[cfg(feature = "trace")] | ||
drop(system_guard); | ||
// tell the executor that the system finished | ||
sender | ||
.try_send(SystemResult { | ||
|
@@ -582,17 +575,17 @@ impl MultiThreadedExecutor { | |
}; | ||
|
||
#[cfg(feature = "trace")] | ||
let task = task.instrument(task_span); | ||
let task = task.instrument( | ||
self.system_task_metadata[system_index] | ||
.system_task_span | ||
.clone(), | ||
); | ||
scope.spawn_on_scope(task); | ||
} else { | ||
let task = async move { | ||
#[cfg(feature = "trace")] | ||
let system_guard = system_span.enter(); | ||
let res = std::panic::catch_unwind(AssertUnwindSafe(|| { | ||
system.run((), world); | ||
})); | ||
#[cfg(feature = "trace")] | ||
drop(system_guard); | ||
// tell the executor that the system finished | ||
sender | ||
.try_send(SystemResult { | ||
|
@@ -612,7 +605,11 @@ impl MultiThreadedExecutor { | |
}; | ||
|
||
#[cfg(feature = "trace")] | ||
let task = task.instrument(task_span); | ||
let task = task.instrument( | ||
self.system_task_metadata[system_index] | ||
.system_task_span | ||
.clone(), | ||
); | ||
scope.spawn_on_scope(task); | ||
} | ||
|
||
|
@@ -718,8 +715,6 @@ unsafe fn evaluate_and_fold_conditions( | |
conditions | ||
.iter_mut() | ||
.map(|condition| { | ||
#[cfg(feature = "trace")] | ||
let _condition_span = info_span!("condition", name = &*condition.name()).entered(); | ||
// SAFETY: The caller ensures that `world` has permission to | ||
// access any data required by the condition. | ||
unsafe { condition.run_unsafe((), world) } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.