Skip to content

Commit 6439f6c

Browse files
committed
timing: Always split histogram with zero as a boundary
If the timing histogram has both positive and negative numbers, then we ensure that zero is used as a boundary and that at least 25% of the bins are dedicated to both positive and negative side so you get a decent level of details on both sides. Obviously that means bin size is different for positive / negative sides. Signed-off-by: Sylvain Munaut <[email protected]>
1 parent 5c6b2cb commit 6439f6c

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

common/timing.cc

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -956,15 +956,42 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
956956
if (print_histogram && slack_histogram.size() > 0) {
957957
unsigned num_bins = 20;
958958
unsigned bar_width = 60;
959+
std::vector<unsigned> bins_count(num_bins);
960+
std::vector<unsigned> bins_bounds(num_bins + 1);
961+
unsigned max_freq = 0;
959962
auto min_slack = slack_histogram.begin()->first;
960963
auto max_slack = slack_histogram.rbegin()->first;
961-
auto bin_size = std::max<unsigned>(1, ceil((max_slack - min_slack + 1) / float(num_bins)));
962-
std::vector<unsigned> bins(num_bins);
963-
unsigned max_freq = 0;
964-
for (const auto &i : slack_histogram) {
965-
auto &bin = bins[(i.first - min_slack) / bin_size];
966-
bin += i.second;
967-
max_freq = std::max(max_freq, bin);
964+
965+
if ((min_slack < 0) && (max_slack > 0)) {
966+
/* Double sided histogram */
967+
/* [0...bin_ofs-1] = neg */
968+
/* [bin_ofs...num_bins-1] = pos */
969+
auto bin_ofs = std::max<unsigned>(
970+
num_bins / 4, std::min<unsigned>(num_bins - (num_bins / 4) - 1,
971+
ceil(float(num_bins) * -min_slack / (max_slack - min_slack))));
972+
auto bin_size_neg = std::max<unsigned>(1, ceil((-min_slack + 1) / float(bin_ofs)));
973+
auto bin_size_pos = std::max<unsigned>(1, ceil((max_slack + 1) / float(num_bins - bin_ofs)));
974+
for (unsigned i = 0; i < bin_ofs; i++)
975+
bins_bounds[i] = (i - bin_ofs) * bin_size_neg;
976+
for (unsigned i = bin_ofs; i <= num_bins; i++)
977+
bins_bounds[i] = (i - bin_ofs) * bin_size_pos;
978+
for (const auto &i : slack_histogram) {
979+
int idx = (i.first < 0) ? (int)bin_ofs + (i.first / (int)bin_size_neg) - 1
980+
: (int)bin_ofs + (i.first / (int)bin_size_pos);
981+
auto &bin = bins_count[idx];
982+
bin += i.second;
983+
max_freq = std::max(max_freq, bin);
984+
}
985+
} else {
986+
/* Single sided histogram */
987+
auto bin_size = std::max<unsigned>(1, ceil((max_slack - min_slack + 1) / float(num_bins)));
988+
for (unsigned i = 0; i <= num_bins; i++)
989+
bins_bounds[i] = min_slack + bin_size * i;
990+
for (const auto &i : slack_histogram) {
991+
auto &bin = bins_count[(i.first - min_slack) / bin_size];
992+
bin += i.second;
993+
max_freq = std::max(max_freq, bin);
994+
}
968995
}
969996
bar_width = std::min(bar_width, max_freq);
970997

@@ -973,9 +1000,9 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
9731000
log_info(" legend: * represents %d endpoint(s)\n", max_freq / bar_width);
9741001
log_info(" + represents [1,%d) endpoint(s)\n", max_freq / bar_width);
9751002
for (unsigned i = 0; i < num_bins; ++i)
976-
log_info("[%6d, %6d) |%s%c\n", min_slack + bin_size * i, min_slack + bin_size * (i + 1),
977-
std::string(bins[i] * bar_width / max_freq, '*').c_str(),
978-
(bins[i] * bar_width) % max_freq > 0 ? '+' : ' ');
1003+
log_info("[%6d, %6d) |%s%c\n", bins_bounds[i], bins_bounds[i + 1],
1004+
std::string(bins_count[i] * bar_width / max_freq, '*').c_str(),
1005+
(bins_count[i] * bar_width) % max_freq > 0 ? '+' : ' ');
9791006
}
9801007
}
9811008

0 commit comments

Comments
 (0)