Profile incremental hashing
This commit is contained in:
parent
c5e344f774
commit
6e33dce9c2
@ -94,31 +94,34 @@ use std::process;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use measureme::{EventId, EventIdBuilder, Profiler, SerializableString, StringId};
|
pub use measureme::EventId;
|
||||||
|
use measureme::{EventIdBuilder, Profiler, SerializableString, StringId};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
struct EventFilter: u32 {
|
struct EventFilter: u32 {
|
||||||
const GENERIC_ACTIVITIES = 1 << 0;
|
const GENERIC_ACTIVITIES = 1 << 0;
|
||||||
const QUERY_PROVIDERS = 1 << 1;
|
const QUERY_PROVIDERS = 1 << 1;
|
||||||
const QUERY_CACHE_HITS = 1 << 2;
|
const QUERY_CACHE_HITS = 1 << 2;
|
||||||
const QUERY_BLOCKED = 1 << 3;
|
const QUERY_BLOCKED = 1 << 3;
|
||||||
const INCR_CACHE_LOADS = 1 << 4;
|
const INCR_CACHE_LOADS = 1 << 4;
|
||||||
|
|
||||||
const QUERY_KEYS = 1 << 5;
|
const QUERY_KEYS = 1 << 5;
|
||||||
const FUNCTION_ARGS = 1 << 6;
|
const FUNCTION_ARGS = 1 << 6;
|
||||||
const LLVM = 1 << 7;
|
const LLVM = 1 << 7;
|
||||||
|
const INCR_RESULT_HASHING = 1 << 8;
|
||||||
|
|
||||||
const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
|
const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
|
||||||
Self::QUERY_PROVIDERS.bits |
|
Self::QUERY_PROVIDERS.bits |
|
||||||
Self::QUERY_BLOCKED.bits |
|
Self::QUERY_BLOCKED.bits |
|
||||||
Self::INCR_CACHE_LOADS.bits;
|
Self::INCR_CACHE_LOADS.bits |
|
||||||
|
Self::INCR_RESULT_HASHING.bits;
|
||||||
|
|
||||||
const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits;
|
const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep this in sync with the `-Z self-profile-events` help message in librustc_session/options.rs
|
// keep this in sync with the `-Z self-profile-events` help message in rustc_session/options.rs
|
||||||
const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
|
const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
|
||||||
("none", EventFilter::empty()),
|
("none", EventFilter::empty()),
|
||||||
("all", EventFilter::all()),
|
("all", EventFilter::all()),
|
||||||
@ -132,6 +135,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
|
|||||||
("function-args", EventFilter::FUNCTION_ARGS),
|
("function-args", EventFilter::FUNCTION_ARGS),
|
||||||
("args", EventFilter::ARGS),
|
("args", EventFilter::ARGS),
|
||||||
("llvm", EventFilter::LLVM),
|
("llvm", EventFilter::LLVM),
|
||||||
|
("incr-result-hashing", EventFilter::INCR_RESULT_HASHING),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Something that uniquely identifies a query invocation.
|
/// Something that uniquely identifies a query invocation.
|
||||||
@ -248,6 +252,15 @@ impl SelfProfilerRef {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start profiling with some event filter for a given event. Profiling continues until the
|
||||||
|
/// TimingGuard returned from this call is dropped.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn generic_activity_with_event(&self, event_id: EventId) -> TimingGuard<'_> {
|
||||||
|
self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| {
|
||||||
|
TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Start profiling a generic activity. Profiling continues until the
|
/// Start profiling a generic activity. Profiling continues until the
|
||||||
/// TimingGuard returned from this call is dropped.
|
/// TimingGuard returned from this call is dropped.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -337,6 +350,19 @@ impl SelfProfilerRef {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start profiling how long it takes to hash query results for incremental compilation.
|
||||||
|
/// Profiling continues until the TimingGuard returned from this call is dropped.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn incr_result_hashing(&self) -> TimingGuard<'_> {
|
||||||
|
self.exec(EventFilter::INCR_RESULT_HASHING, |profiler| {
|
||||||
|
TimingGuard::start(
|
||||||
|
profiler,
|
||||||
|
profiler.incremental_result_hashing_event_kind,
|
||||||
|
EventId::INVALID,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn instant_query_event(
|
fn instant_query_event(
|
||||||
&self,
|
&self,
|
||||||
@ -364,6 +390,10 @@ impl SelfProfilerRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_or_alloc_cached_string(&self, s: &'static str) -> Option<StringId> {
|
||||||
|
self.profiler.as_ref().map(|p| p.get_or_alloc_cached_string(s))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enabled(&self) -> bool {
|
pub fn enabled(&self) -> bool {
|
||||||
self.profiler.is_some()
|
self.profiler.is_some()
|
||||||
@ -388,6 +418,7 @@ pub struct SelfProfiler {
|
|||||||
query_event_kind: StringId,
|
query_event_kind: StringId,
|
||||||
generic_activity_event_kind: StringId,
|
generic_activity_event_kind: StringId,
|
||||||
incremental_load_result_event_kind: StringId,
|
incremental_load_result_event_kind: StringId,
|
||||||
|
incremental_result_hashing_event_kind: StringId,
|
||||||
query_blocked_event_kind: StringId,
|
query_blocked_event_kind: StringId,
|
||||||
query_cache_hit_event_kind: StringId,
|
query_cache_hit_event_kind: StringId,
|
||||||
}
|
}
|
||||||
@ -408,6 +439,8 @@ impl SelfProfiler {
|
|||||||
let query_event_kind = profiler.alloc_string("Query");
|
let query_event_kind = profiler.alloc_string("Query");
|
||||||
let generic_activity_event_kind = profiler.alloc_string("GenericActivity");
|
let generic_activity_event_kind = profiler.alloc_string("GenericActivity");
|
||||||
let incremental_load_result_event_kind = profiler.alloc_string("IncrementalLoadResult");
|
let incremental_load_result_event_kind = profiler.alloc_string("IncrementalLoadResult");
|
||||||
|
let incremental_result_hashing_event_kind =
|
||||||
|
profiler.alloc_string("IncrementalResultHashing");
|
||||||
let query_blocked_event_kind = profiler.alloc_string("QueryBlocked");
|
let query_blocked_event_kind = profiler.alloc_string("QueryBlocked");
|
||||||
let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit");
|
let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit");
|
||||||
|
|
||||||
@ -451,6 +484,7 @@ impl SelfProfiler {
|
|||||||
query_event_kind,
|
query_event_kind,
|
||||||
generic_activity_event_kind,
|
generic_activity_event_kind,
|
||||||
incremental_load_result_event_kind,
|
incremental_load_result_event_kind,
|
||||||
|
incremental_result_hashing_event_kind,
|
||||||
query_blocked_event_kind,
|
query_blocked_event_kind,
|
||||||
query_cache_hit_event_kind,
|
query_cache_hit_event_kind,
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::profiling::QueryInvocationId;
|
use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef};
|
||||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
|
||||||
use rustc_data_structures::sharded::{self, Sharded};
|
use rustc_data_structures::sharded::{self, Sharded};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
@ -36,6 +35,11 @@ pub struct DepGraph<K: DepKind> {
|
|||||||
/// each task has a `DepNodeIndex` that uniquely identifies it. This unique
|
/// each task has a `DepNodeIndex` that uniquely identifies it. This unique
|
||||||
/// ID is used for self-profiling.
|
/// ID is used for self-profiling.
|
||||||
virtual_dep_node_index: Lrc<AtomicU32>,
|
virtual_dep_node_index: Lrc<AtomicU32>,
|
||||||
|
|
||||||
|
/// The cached event id for profiling node interning. This saves us
|
||||||
|
/// from having to look up the event id every time we intern a node
|
||||||
|
/// which may incur too much overhead.
|
||||||
|
node_intern_event_id: Option<EventId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
@ -130,6 +134,10 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
);
|
);
|
||||||
debug_assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE);
|
debug_assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE);
|
||||||
|
|
||||||
|
let node_intern_event_id = profiler
|
||||||
|
.get_or_alloc_cached_string("incr_comp_intern_dep_graph_node")
|
||||||
|
.map(EventId::from_label);
|
||||||
|
|
||||||
DepGraph {
|
DepGraph {
|
||||||
data: Some(Lrc::new(DepGraphData {
|
data: Some(Lrc::new(DepGraphData {
|
||||||
previous_work_products: prev_work_products,
|
previous_work_products: prev_work_products,
|
||||||
@ -141,11 +149,16 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
colors: DepNodeColorMap::new(prev_graph_node_count),
|
colors: DepNodeColorMap::new(prev_graph_node_count),
|
||||||
})),
|
})),
|
||||||
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
|
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
|
||||||
|
node_intern_event_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_disabled() -> DepGraph<K> {
|
pub fn new_disabled() -> DepGraph<K> {
|
||||||
DepGraph { data: None, virtual_dep_node_index: Lrc::new(AtomicU32::new(0)) }
|
DepGraph {
|
||||||
|
data: None,
|
||||||
|
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
|
||||||
|
node_intern_event_id: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if we are actually building the full dep-graph, and `false` otherwise.
|
/// Returns `true` if we are actually building the full dep-graph, and `false` otherwise.
|
||||||
@ -244,10 +257,15 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads);
|
let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads);
|
||||||
|
|
||||||
let mut hcx = dcx.create_stable_hashing_context();
|
let mut hcx = dcx.create_stable_hashing_context();
|
||||||
|
let hashing_timer = dcx.profiler().incr_result_hashing();
|
||||||
let current_fingerprint = hash_result(&mut hcx, &result);
|
let current_fingerprint = hash_result(&mut hcx, &result);
|
||||||
|
|
||||||
let print_status = cfg!(debug_assertions) && dcx.sess().opts.debugging_opts.dep_tasks;
|
let print_status = cfg!(debug_assertions) && dcx.sess().opts.debugging_opts.dep_tasks;
|
||||||
|
|
||||||
|
// Get timer for profiling `DepNode` interning
|
||||||
|
let node_intern_timer = self
|
||||||
|
.node_intern_event_id
|
||||||
|
.map(|eid| dcx.profiler().generic_activity_with_event(eid));
|
||||||
// Intern the new `DepNode`.
|
// Intern the new `DepNode`.
|
||||||
let (dep_node_index, prev_and_color) = data.current.intern_node(
|
let (dep_node_index, prev_and_color) = data.current.intern_node(
|
||||||
dcx.profiler(),
|
dcx.profiler(),
|
||||||
@ -257,6 +275,9 @@ impl<K: DepKind> DepGraph<K> {
|
|||||||
current_fingerprint,
|
current_fingerprint,
|
||||||
print_status,
|
print_status,
|
||||||
);
|
);
|
||||||
|
drop(node_intern_timer);
|
||||||
|
|
||||||
|
hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
|
||||||
|
|
||||||
if let Some((prev_index, color)) = prev_and_color {
|
if let Some((prev_index, color)) = prev_and_color {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
|
@ -1249,7 +1249,7 @@ options! {
|
|||||||
"specify the events recorded by the self profiler;
|
"specify the events recorded by the self profiler;
|
||||||
for example: `-Z self-profile-events=default,query-keys`
|
for example: `-Z self-profile-events=default,query-keys`
|
||||||
all options: none, all, default, generic-activity, query-provider, query-cache-hit
|
all options: none, all, default, generic-activity, query-provider, query-cache-hit
|
||||||
query-blocked, incr-cache-load, query-keys, function-args, args, llvm"),
|
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm"),
|
||||||
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||||
"make the current crate share its generic instantiations"),
|
"make the current crate share its generic instantiations"),
|
||||||
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
|
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user