-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[BOLT][NFCI] Report perf script time #147232
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
Conversation
Created using spr 1.3.4
@llvm/pr-subscribers-bolt Author: Amir Ayupov (aaupov) ChangesLeverage Switch buildid-list command to non-waiting Test Plan: NFC Full diff: https://github.com/llvm/llvm-project/pull/147232.diff 2 Files Affected:
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 98e4bba872846..c7400b0d45ca8 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -236,8 +236,7 @@ class DataAggregator : public DataReader {
/// Launch a perf subprocess with given args and save output for later
/// parsing.
- void launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
- const char *ArgsString, bool Wait);
+ void launchPerfProcess(StringRef Name, PerfProcessInfo &PPI, StringRef Args);
/// Delete all temporary files created to hold the output generated by spawned
/// subprocesses during the aggregation job
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 88229bb31a2ad..c60591c02b6c0 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -197,34 +197,27 @@ void DataAggregator::start() {
if (opts::BasicAggregation) {
launchPerfProcess("events without LBR", MainEventsPPI,
- "script -F pid,event,ip",
- /*Wait = */ false);
+ "script -F pid,event,ip");
} else if (!opts::ITraceAggregation.empty()) {
// Disable parsing memory profile from trace data, unless requested by user.
if (!opts::ParseMemProfile.getNumOccurrences())
opts::ParseMemProfile = false;
-
- std::string ItracePerfScriptArgs = llvm::formatv(
- "script -F pid,brstack --itrace={0}", opts::ITraceAggregation);
launchPerfProcess("branch events with itrace", MainEventsPPI,
- ItracePerfScriptArgs.c_str(),
- /*Wait = */ false);
+ "script -F pid,brstack --itrace=" +
+ opts::ITraceAggregation);
} else {
- launchPerfProcess("branch events", MainEventsPPI, "script -F pid,brstack",
- /*Wait = */ false);
+ launchPerfProcess("branch events", MainEventsPPI, "script -F pid,brstack");
}
if (opts::ParseMemProfile)
- launchPerfProcess("mem events", MemEventsPPI, "script -F pid,event,addr,ip",
- /*Wait = */ false);
+ launchPerfProcess("mem events", MemEventsPPI,
+ "script -F pid,event,addr,ip");
launchPerfProcess("process events", MMapEventsPPI,
- "script --show-mmap-events --no-itrace",
- /*Wait = */ false);
+ "script --show-mmap-events --no-itrace");
launchPerfProcess("task events", TaskEventsPPI,
- "script --show-task-events --no-itrace",
- /*Wait = */ false);
+ "script --show-task-events --no-itrace");
}
void DataAggregator::abort() {
@@ -246,13 +239,13 @@ void DataAggregator::abort() {
}
void DataAggregator::launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
- const char *ArgsString, bool Wait) {
+ StringRef Args) {
SmallVector<StringRef, 4> Argv;
outs() << "PERF2BOLT: spawning perf job to read " << Name << '\n';
Argv.push_back(PerfPath.data());
- StringRef(ArgsString).split(Argv, ' ');
+ Args.split(Argv, ' ');
Argv.push_back("-f");
Argv.push_back("-i");
Argv.push_back(Filename.c_str());
@@ -286,64 +279,45 @@ void DataAggregator::launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
<< "\n";
});
- if (Wait)
- PPI.PI.ReturnCode = sys::ExecuteAndWait(PerfPath.data(), Argv,
- /*envp*/ std::nullopt, Redirects);
- else
- PPI.PI = sys::ExecuteNoWait(PerfPath.data(), Argv, /*envp*/ std::nullopt,
- Redirects);
+ PPI.PI = sys::ExecuteNoWait(PerfPath.data(), Argv, /*envp*/ std::nullopt,
+ Redirects);
}
void DataAggregator::processFileBuildID(StringRef FileBuildID) {
+ auto WarningCallback = [](int ReturnCode, StringRef ErrBuf) {
+ errs() << "PERF-ERROR: return code " << ReturnCode << "\n" << ErrBuf;
+ };
+
PerfProcessInfo BuildIDProcessInfo;
- launchPerfProcess("buildid list",
- BuildIDProcessInfo,
- "buildid-list",
- /*Wait = */true);
-
- if (BuildIDProcessInfo.PI.ReturnCode != 0) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(BuildIDProcessInfo.StderrPath.data());
- StringRef ErrBuf = (*MB)->getBuffer();
-
- errs() << "PERF-ERROR: return code " << BuildIDProcessInfo.PI.ReturnCode
- << '\n';
- errs() << ErrBuf;
+ launchPerfProcess("buildid list", BuildIDProcessInfo, "buildid-list");
+ if (prepareToParse("buildid", BuildIDProcessInfo, WarningCallback))
return;
- }
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(BuildIDProcessInfo.StdoutPath.data());
- if (std::error_code EC = MB.getError()) {
- errs() << "Cannot open " << BuildIDProcessInfo.StdoutPath.data() << ": "
- << EC.message() << "\n";
+ std::optional<StringRef> FileName = getFileNameForBuildID(FileBuildID);
+ if (FileName && *FileName == sys::path::filename(BC->getFilename())) {
+ outs() << "PERF2BOLT: matched build-id and file name\n";
return;
}
- FileBuf = std::move(*MB);
- ParsingBuf = FileBuf->getBuffer();
-
- std::optional<StringRef> FileName = getFileNameForBuildID(FileBuildID);
- if (!FileName) {
- if (hasAllBuildIDs()) {
- errs() << "PERF2BOLT-ERROR: failed to match build-id from perf output. "
- "This indicates the input binary supplied for data aggregation "
- "is not the same recorded by perf when collecting profiling "
- "data, or there were no samples recorded for the binary. "
- "Use -ignore-build-id option to override.\n";
- if (!opts::IgnoreBuildID)
- abort();
- } else {
- errs() << "PERF2BOLT-WARNING: build-id will not be checked because perf "
- "data was recorded without it\n";
- return;
- }
- } else if (*FileName != llvm::sys::path::filename(BC->getFilename())) {
+ if (FileName) {
errs() << "PERF2BOLT-WARNING: build-id matched a different file name\n";
BuildIDBinaryName = std::string(*FileName);
- } else {
- outs() << "PERF2BOLT: matched build-id and file name\n";
+ return;
}
+
+ if (!hasAllBuildIDs()) {
+ errs() << "PERF2BOLT-WARNING: build-id will not be checked because perf "
+ "data was recorded without it\n";
+ return;
+ }
+
+ errs() << "PERF2BOLT-ERROR: failed to match build-id from perf output. "
+ "This indicates the input binary supplied for data aggregation "
+ "is not the same recorded by perf when collecting profiling "
+ "data, or there were no samples recorded for the binary. "
+ "Use -ignore-build-id option to override.\n";
+ if (!opts::IgnoreBuildID)
+ abort();
}
bool DataAggregator::checkPerfDataMagic(StringRef FileName) {
@@ -432,7 +406,8 @@ int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
std::string Error;
outs() << "PERF2BOLT: waiting for perf " << Name
<< " collection to finish...\n";
- sys::ProcessInfo PI = sys::Wait(Process.PI, std::nullopt, &Error);
+ std::optional<sys::ProcessStatistics> PS;
+ sys::ProcessInfo PI = sys::Wait(Process.PI, std::nullopt, &Error, &PS);
if (!Error.empty()) {
errs() << "PERF-ERROR: " << PerfPath << ": " << Error << "\n";
@@ -440,6 +415,15 @@ int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
exit(1);
}
+ LLVM_DEBUG({
+ const float UserSec = 1.f * PS->UserTime.count() / 1e6;
+ const float TotalSec = 1.f * PS->TotalTime.count() / 1e6;
+ const float PeakGiB = 1.f * PS->PeakMemory / (1 << 20);
+ dbgs() << formatv("Finished in {0:f2}s user time, {1:f2}s total time, "
+ "{2:f2} GiB peak RSS\n",
+ UserSec, TotalSec, PeakGiB);
+ });
+
if (PI.ReturnCode != 0) {
ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorMB =
MemoryBuffer::getFileOrSTDIN(Process.StderrPath.data());
|
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.
Looks good, thanks for the cleanup and the stats!
Leverage
sys::ProcessStatistics
to report the run time and memoryusage of perf script processes launched when reading perf data.
The reporting is enabled in debug mode with
-debug-only=aggregator
.Switch buildid-list command to non-waiting
launchPerfProcess
to getits runtime as well, unifying it with the rest of perf script processes.
Test Plan: NFC