Allow building heatmaps from basic sampled events with `-nl`.
I find that this is useful for finding event hotspots. Reviewed By: rafauler Differential Revision: https://reviews.llvm.org/D123067
This commit is contained in:
parent
fe2478d44e
commit
0c13d97e2b
|
@ -20,8 +20,10 @@ or if you want to monitor the existing process(es):
|
|||
$ perf record -e cycles:u -j any,u [-p PID|-a] -- sleep <interval>
|
||||
```
|
||||
|
||||
Note that at the moment running with LBR (`-j any,u` or `-b`) is
|
||||
a requirement.
|
||||
Running with LBR (`-j any,u` or `-b`) is recommended. Heatmaps can be generated
|
||||
from basic events by using the llvm-bolt-heatmap option `-nl` (no LBR) but
|
||||
such heatmaps do not have the coverage provided by LBR and may only be useful
|
||||
for finding event hotspots at larger code block granularities.
|
||||
|
||||
Once the run is complete, and `perf.data` is generated, run llvm-bolt-heatmap:
|
||||
|
||||
|
|
|
@ -1296,37 +1296,55 @@ std::error_code DataAggregator::printLBRHeatMap() {
|
|||
uint64_t NumTotalSamples = 0;
|
||||
|
||||
while (hasData()) {
|
||||
ErrorOr<PerfBranchSample> SampleRes = parseBranchSample();
|
||||
if (std::error_code EC = SampleRes.getError()) {
|
||||
if (EC == errc::no_such_process)
|
||||
continue;
|
||||
return EC;
|
||||
}
|
||||
|
||||
PerfBranchSample &Sample = SampleRes.get();
|
||||
|
||||
// LBRs are stored in reverse execution order. NextLBR refers to the next
|
||||
// executed branch record.
|
||||
const LBREntry *NextLBR = nullptr;
|
||||
for (const LBREntry &LBR : Sample.LBR) {
|
||||
if (NextLBR) {
|
||||
// Record fall-through trace.
|
||||
const uint64_t TraceFrom = LBR.To;
|
||||
const uint64_t TraceTo = NextLBR->From;
|
||||
++FallthroughLBRs[Trace(TraceFrom, TraceTo)].InternCount;
|
||||
if (opts::BasicAggregation) {
|
||||
ErrorOr<PerfBasicSample> SampleRes = parseBasicSample();
|
||||
if (std::error_code EC = SampleRes.getError()) {
|
||||
if (EC == errc::no_such_process)
|
||||
continue;
|
||||
return EC;
|
||||
}
|
||||
NextLBR = &LBR;
|
||||
PerfBasicSample &Sample = SampleRes.get();
|
||||
HM.registerAddress(Sample.PC);
|
||||
NumTotalSamples++;
|
||||
} else {
|
||||
ErrorOr<PerfBranchSample> SampleRes = parseBranchSample();
|
||||
if (std::error_code EC = SampleRes.getError()) {
|
||||
if (EC == errc::no_such_process)
|
||||
continue;
|
||||
return EC;
|
||||
}
|
||||
|
||||
PerfBranchSample &Sample = SampleRes.get();
|
||||
|
||||
// LBRs are stored in reverse execution order. NextLBR refers to the next
|
||||
// executed branch record.
|
||||
const LBREntry *NextLBR = nullptr;
|
||||
for (const LBREntry &LBR : Sample.LBR) {
|
||||
if (NextLBR) {
|
||||
// Record fall-through trace.
|
||||
const uint64_t TraceFrom = LBR.To;
|
||||
const uint64_t TraceTo = NextLBR->From;
|
||||
++FallthroughLBRs[Trace(TraceFrom, TraceTo)].InternCount;
|
||||
}
|
||||
NextLBR = &LBR;
|
||||
}
|
||||
if (!Sample.LBR.empty()) {
|
||||
HM.registerAddress(Sample.LBR.front().To);
|
||||
HM.registerAddress(Sample.LBR.back().From);
|
||||
}
|
||||
NumTotalSamples += Sample.LBR.size();
|
||||
}
|
||||
if (!Sample.LBR.empty()) {
|
||||
HM.registerAddress(Sample.LBR.front().To);
|
||||
HM.registerAddress(Sample.LBR.back().From);
|
||||
}
|
||||
NumTotalSamples += Sample.LBR.size();
|
||||
}
|
||||
|
||||
if (!NumTotalSamples) {
|
||||
errs() << "HEATMAP-ERROR: no LBR traces detected in profile. "
|
||||
"Cannot build heatmap.\n";
|
||||
if (!opts::BasicAggregation) {
|
||||
errs() << "HEATMAP-ERROR: no LBR traces detected in profile. "
|
||||
"Cannot build heatmap. Use -nl for building heatmap from "
|
||||
"basic events.\n";
|
||||
} else {
|
||||
errs() << "HEATMAP-ERROR: no samples detected in profile. "
|
||||
"Cannot build heatmap.";
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue