[llvm] [llvm-profgen] Improve sample profile density (PR #92144)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 17 18:40:22 PDT 2024
================
@@ -768,9 +745,79 @@ void ProfileGenerator::populateBoundarySamplesForAllFunctions(
}
}
+void ProfileGeneratorBase::calculateDensity(
+ const FunctionSamples &FSamples,
+ std::vector<std::pair<double, uint64_t>> &DensityList,
+ uint64_t &TotalProfileSamples) {
+ uint64_t TotalBodySamples = 0;
+ uint64_t FuncBodySize = 0;
+ for (const auto &I : FSamples.getBodySamples()) {
+ TotalBodySamples += I.second.getSamples();
+ FuncBodySize++;
+ }
+
+ // The whole function could be inlined and optimized out, use the callsite
+ // head samples instead to estimate the body count.
+ if (FuncBodySize == 0) {
+ for (const auto &CallsiteSamples : FSamples.getCallsiteSamples()) {
+ FuncBodySize++;
+ for (const auto &Callee : CallsiteSamples.second) {
+ calculateDensity(Callee.second, DensityList, TotalProfileSamples);
+ TotalBodySamples += Callee.second.getHeadSamplesEstimate();
+ }
+ }
+ }
+
+ if (FuncBodySize == 0)
+ return;
+
+ double FuncDensity = static_cast<double>(TotalBodySamples) / FuncBodySize;
+ TotalProfileSamples += TotalBodySamples;
+ DensityList.emplace_back(FuncDensity, TotalBodySamples);
+}
+
+// Calculate Profile-density:
+// Calculate the density for each function and sort them in descending order,
+// iterate them once their accumulated total samples exceeds the
+// percentage_threshold(cut-off) of total profile samples, the profile-density
+// is the last(minimum) function-density of the processed functions, which means
+// all the functions hot to perf are on good density if the profile-density is
+// good. The percentage_threshold(--profile-density-cutoff-hot) is configurable
+// depending on how much regression the system want to tolerate.
+double
+ProfileGeneratorBase::calculateDensity(const SampleProfileMap &Profiles) {
+ double ProfileDensity = 0.0;
+
+ uint64_t TotalProfileSamples = 0;
+ // A list of the function profile density and its total samples.
+ std::vector<std::pair<double, uint64_t>> FuncDensityList;
+ for (const auto &I : Profiles)
+ calculateDensity(I.second, FuncDensityList, TotalProfileSamples);
+
+ // Sorted by the density in descending order.
+ llvm::stable_sort(FuncDensityList, [&](const std::pair<double, uint64_t> &A,
+ const std::pair<double, uint64_t> &B) {
+ if (A.first != B.first)
+ return A.first > B.first;
+ return A.second < B.second;
+ });
+
+ uint64_t AccumulatedSamples = 0;
+ for (const auto &P : FuncDensityList) {
+ AccumulatedSamples += P.second;
+ ProfileDensity = P.first;
+ if (AccumulatedSamples >= TotalProfileSamples *
+ static_cast<float>(ProfileDensityCutOffHot) /
+ 1000000)
+ break;
----------------
WenleiHe wrote:
nit: fold the exit condition into a while loop condition?
https://github.com/llvm/llvm-project/pull/92144
More information about the llvm-commits
mailing list