Skip to content

Commit

Permalink
improve handling of spans from events
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed May 17, 2023
1 parent 70f2861 commit 6dd44f1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 32 additions & 23 deletions crates/turbopack-convert-trace/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fn main() {
}

let mut all_self_times = Vec::new();
let mut name_counts: HashMap<&str, usize> = HashMap::new();
let mut name_counts: HashMap<Cow<'_, str>, usize> = HashMap::new();

for FullTraceRow { ts, data } in trace_rows {
match data {
Expand All @@ -109,7 +109,7 @@ fn main() {
spans[internal_id].parent = internal_parent;
let parent = &mut spans[internal_parent];
parent.items.push(SpanItem::Child(internal_id));
*name_counts.entry(name).or_default() += 1;
*name_counts.entry(Cow::Borrowed(name)).or_default() += 1;
}
TraceRow::End { id } => {
// id might be reused
Expand All @@ -135,7 +135,7 @@ fn main() {
if end > start {
span.items.push(SpanItem::SelfTime {
start,
duration: end.saturating_sub(start),
duration: end - start,
});
all_self_times.push(Element {
range: start..end,
Expand All @@ -153,20 +153,23 @@ fn main() {
let internal_parent =
parent.map_or(0, |id| ensure_span(&mut active_ids, &mut spans, id));
if duration > 0 {
*name_counts.entry(name.clone()).or_default() += 1;
let internal_id = spans.len();
let start = ts - duration;
spans.push(Span {
parent: internal_parent,
name,
target: "".into(),
start: ts,
end: ts + duration,
start,
end: ts,
self_start: None,
items: vec![SpanItem::SelfTime {
start: ts - duration,
duration,
}],
items: vec![SpanItem::SelfTime { start, duration }],
values,
});
all_self_times.push(Element {
range: start..ts,
value: (internal_id, 0),
});
let parent = &mut spans[internal_parent];
parent.items.push(SpanItem::Child(internal_id));
}
Expand All @@ -176,7 +179,7 @@ fn main() {

eprintln!(" done ({} spans)", spans.len());

let mut name_counts: Vec<(&str, usize)> = name_counts.into_iter().collect();
let mut name_counts: Vec<(Cow<'_, str>, usize)> = name_counts.into_iter().collect();
name_counts.sort_by_key(|(_, count)| Reverse(*count));

eprintln!("Top 10 span names:");
Expand All @@ -188,6 +191,7 @@ fn main() {
print!(r#"{{"ph":"M","pid":1,"name":"thread_name","tid":0,"args":{{"name":"Single CPU"}}}}"#);
pjson!(r#"{{"ph":"M","pid":2,"name":"thread_name","tid":0,"args":{{"name":"Scaling CPU"}}}}"#);

let busy_len = all_self_times.len();
let busy = all_self_times.into_iter().collect::<IntervalTree<_, _>>();

if threads {
Expand Down Expand Up @@ -234,37 +238,42 @@ fn main() {
stack
};

for &Element {
range: Range { start, .. },
value: (id, index),
} in busy.iter_sorted()
for (
i,
&Element {
range: Range { start, end },
value: (id, _),
},
) in busy.iter_sorted().enumerate()
{
let span = &spans[id];
let SpanItem::SelfTime { start: _, duration } = &span.items[index] else {
panic!("Expected index to self time");
};
if i % 1000 == 0 {
eprint!("\rDistributing time into virtual threads... {i} / {busy_len}",);
}
let stack = get_stack(id);
let thread = find_thread(&mut virtual_threads, &stack, start);

let virtual_thread = &mut virtual_threads[thread];
let ts = virtual_thread.ts;
let thread_stack = &mut virtual_thread.stack;

let long_idle = virtual_thread.ts + 10000 < start;

// Leave old spans on that thread
while !thread_stack.is_empty()
&& thread_stack.last() != stack.get(thread_stack.len() - 1)
&& (long_idle || thread_stack.last() != stack.get(thread_stack.len() - 1))
{
let id = thread_stack.pop().unwrap();
let span = &spans[id];
pjson!(
r#"{{"ph":"E","pid":3,"ts":{ts},"name":{},"cat":{},"tid":{thread}}}"#,
r#"{{"ph":"E","pid":3,"ts":{ts},"name":{},"cat":{},"tid":{thread},"_id":{id},"_stack":"{:?}"}}"#,
serde_json::to_string(&span.name).unwrap(),
serde_json::to_string(&span.target).unwrap(),
stack.get(thread_stack.len())
);
}

// Advance thread time to start
if virtual_thread.ts < start {
if virtual_thread.ts + 100 < start {
if !thread_stack.is_empty() {
pjson!(
r#"{{"ph":"B","pid":3,"ts":{ts},"name":"idle","cat":"idle","tid":{thread}}}"#,
Expand All @@ -281,13 +290,13 @@ fn main() {
thread_stack.push(*id);
let span = &spans[*id];
pjson!(
r#"{{"ph":"B","pid":3,"ts":{start},"name":{},"cat":{},"tid":{thread}}}"#,
r#"{{"ph":"B","pid":3,"ts":{start},"name":{},"cat":{},"tid":{thread},"_id":{id}}}"#,
serde_json::to_string(&span.name).unwrap(),
serde_json::to_string(&span.target).unwrap(),
);
}

virtual_thread.ts += duration;
virtual_thread.ts = end;
}

// Leave all threads
Expand Down

0 comments on commit 6dd44f1

Please sign in to comment.