Lines Matching +full:duration +full:- +full:us

1 //===- xray-stacks.cpp: XRay Function Call Stack Accounting ---------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements stack-based accounting. It takes XRay traces, and
15 //===----------------------------------------------------------------------===//
20 #include "func-id-helper.h"
21 #include "trie-node.h"
22 #include "xray-registry.h"
42 StackKeepGoing("keep-going", cl::desc("Keep going on errors encountered"),
45 cl::desc("Alias for -keep-going"));
55 cl::desc("Alias for -instr_map"));
58 SeparateThreadStacks("per-thread-stacks",
63 AggregateThreads("aggregate-threads",
68 DumpAllStacks("all-stacks",
70 "By default separates stacks per-thread."),
73 cl::desc("Alias for -all-stacks"));
80 "stack-format",
82 "output in. Only applies with all-stacks."),
85 "Human readable output. Only valid without -all-stacks."),
88 "Only valid with -all-stacks.")),
98 "aggregation-type",
119 Converter->SymbolOrNumber(Item.FuncId), Item.TId,
143 /// - Total time: amount of time/cycles accounted for in the traces.
144 /// - Stack count: number of times a specific stack appears in the
146 /// - Cumulative stack time: amount of time spent in a stack accumulated
148 /// - Cumulative local time: amount of time spent in each instrumented
166 /// 1. When unwinding, record the duration of each unwound function associated
169 /// Step Duration (? means has start time)
172 /// push b <start time> a = ?, a->b = ?
173 /// push c <start time> a = ?, a->b = ?, a->b->c = ?
174 /// pop c <end time> a = ?, a->b = ?, emit duration(a->b->c)
175 /// pop b <end time> a = ?, emit duration(a->b)
176 /// push c <start time> a = ?, a->c = ?
177 /// pop c <end time> a = ?, emit duration(a->c)
178 /// pop a <end time> emit duration(a)
184 /// c : [<id("a->b->c"), [durations]>, <id("a->c"), [durations]>]
185 /// b : [<id("a->b"), [durations]>]
188 /// This allows us to compute, for each stack id, and each function that
191 /// - median
192 /// - 99th percentile
193 /// - mean + stddev
194 /// - count
200 /// Computing this data also allows us to implement lookup by call stack nodes,
219 /// ----------------...
231 /// To do this we require a Trie data structure that will allow us to represent
244 /// a -> b -> c
246 /// | +--> d
248 /// +--> c
270 for (auto duration : Left.TerminalDurations)
271 Data.TerminalDurations.push_back(duration);
272 for (auto duration : Right.TerminalDurations)
273 Data.TerminalDurations.push_back(duration);
275 for (auto duration : Left.IntermediateDurations)
276 Data.IntermediateDurations.push_back(duration);
277 for (auto duration : Right.IntermediateDurations)
278 Data.IntermediateDurations.push_back(duration);
292 auto TopSum = std::accumulate(Node->ExtraData.TerminalDurations.begin(),
293 Node->ExtraData.TerminalDurations.end(), 0uLL);
294 return std::accumulate(Node->ExtraData.IntermediateDurations.begin(),
295 Node->ExtraData.IntermediateDurations.end(), TopSum);
303 return Node->ExtraData.TerminalDurations.size() +
304 Node->ExtraData.IntermediateDurations.size();
345 [&](StackTrieNode *N) { return N->FuncId == FuncId; });
372 state->wasLastRecordExit = false;
385 auto I = find_if(Top.first->Callees,
386 [&](StackTrieNode *N) { return N->FuncId == R.FuncId; });
387 if (I == Top.first->Callees.end()) {
391 Top.first->Callees.emplace_back(N);
404 bool wasLastRecordExit = state->wasLastRecordExit;
405 state->wasLastRecordExit = true;
419 return E.first->FuncId == R.FuncId;
430 for (auto &E : make_range(I, TS.end() - 1))
431 E.first->ExtraData.IntermediateDurations.push_back(
432 std::max(E.second, R.TSC) - std::min(E.second, R.TSC));
435 Deepest.first->ExtraData.IntermediateDurations.push_back(
436 std::max(Deepest.second, R.TSC) - std::min(Deepest.second, R.TSC));
438 Deepest.first->ExtraData.TerminalDurations.push_back(
439 std::max(Deepest.second, R.TSC) - std::min(Deepest.second, R.TSC));
454 for (auto *F = Top; F != nullptr; F = F->Parent)
457 OS << formatv("{0,-5} {1,-60} {2,+12} {3,+16}\n", "lvl", "function",
460 auto Sum = std::accumulate(F->ExtraData.IntermediateDurations.begin(),
461 F->ExtraData.IntermediateDurations.end(), 0LL);
462 auto FuncId = FN.SymbolOrNumber(F->FuncId);
463 OS << formatv("#{0,-4} {1,-60} {2,+12} {3,+16}\n", Level++,
465 F->ExtraData.IntermediateDurations.size(), Sum);
469 std::accumulate(Leaf->ExtraData.TerminalDurations.begin(),
470 Leaf->ExtraData.TerminalDurations.end(), 0LL);
471 auto LeafFuncId = FN.SymbolOrNumber(Leaf->FuncId);
472 OS << formatv("#{0,-4} {1,-60} {2,+12} {3,+16}\n", Level++,
475 Leaf->ExtraData.TerminalDurations.size(), LeafSum);
525 return Node->FuncId == elem->FuncId;
568 for (const auto *C : Top->Callees)
587 while (lineage.back()->Parent != nullptr)
588 lineage.push_back(lineage.back()->Parent);
590 OS << Converter.SymbolOrNumber(lineage.back()->FuncId) << ";";
602 // - Total number of unique stacks
603 // - Top 10 stacks by count
604 // - Top 10 stacks by aggregate duration
623 if (!Top->ExtraData.TerminalDurations.empty()) {
626 std::accumulate(Top->ExtraData.TerminalDurations.begin(),
627 Top->ExtraData.TerminalDurations.end(), 0uLL);
637 std::make_pair(Top, Top->ExtraData.TerminalDurations.size());
644 for (const auto *C : Top->Callees)
681 static CommandRegistration Unused(&Stack, []() -> Error {
682 // Load each file provided as a command-line argument. For each one of them
705 Twine("Can't specify a non-human format without -all-stacks."),
710 Twine("You must specify a non-human format when reporting with "
711 "-all-stacks."),