in Extremem/src/main/java/com/amazon/corretto/benchmark/extremem/RelativeTimeMetrics.java [1370:1592]
void repack(long[] histo_columns, long lb, long histo_span) {
for (int i = 0; i < HistoColumnCount; i++)
histo_columns[i] = 0;
int index = fbi;
for (int i = 0; i < biu; i++) {
// Every data "bucket" has a hit_rate which is the total number
// of samples divided by the number of 256-microsecond intervals
// spanned by this bucket.
// Since data buckets may not align exactly with report buckets,
// we need a way to map between them.
// Model each data bucket's distribution by assuming linear
// progression of hit_rate throughout the interval of time
// spanned by the bucket, with the hit_rate at the beginning of
// the interval matching the preceding bucket's hit_rate and the
// hit_rate at the end of the interval matching the hit_rate of
// the interval that follows.
// Use floating point y-intercept and slope to model each
// data bucket's distribution. y-intercept is relative to the
// a time value of zero. Thus, the y-intercept value may be
// negative.
// To compute how much of a particular data bucket pertains to a
// particular reporting quantum, take the calculate the y-value
// at the midpoint of the reporting quantum, rounding fractional
// results to the nearest integer.
// For complete "integrity", correct round-off errors by summing
// the contributions over all reported quanta and adding or
// subtracting to report totals, working from the center time of
// the data bucket's time span outward.
float right_rate, left_rate;
if (buckets[index] > 0) {
int segment_quanta;
int bucket_tally = buckets[index];
float my_slope;
float my_intercept;
long segment_start;
if (i == 0) { // use sis instead of region span
long start_of_span = sis;
int end_index = incrIndex(index);
long end_of_span = bucket_bounds[end_index];
segment_start = truncate256(start_of_span);
// end_of_interval and segment_start are both multiples of 256
segment_quanta = (int) ((end_of_span - segment_start) / 256);
float this_rate = ((float) buckets[index]) / segment_quanta;
left_rate = 0.0F;
if (biu > 1) {
int next_index = incrIndex(index);
float right_tally = (float) buckets[next_index];
right_rate = right_tally / (spanAt(next_index) / 256);
} else
right_rate = this_rate * 2;
// Log the sis value within the first bucket now.
// Spread the remaining tally values as appropriate.
addToReportTally(histo_columns, lb, histo_span,
sis, 1);
bucket_tally--;
} else if (i + 1 == biu) {
segment_start = bucket_bounds[index];
long end_of_span = truncate256(lis);
// In the case that lis equals segment_start, we need to expand this segment_quanta calculation
if (end_of_span <= lis)
end_of_span += 256;
segment_quanta = (int) ((end_of_span - segment_start) / 256);
float this_rate = ((float) buckets[index] / segment_quanta);
if (biu > 1) {
int prev_index = decrIndex(index);
float left_tally = (float) buckets[prev_index];
left_rate = left_tally / (spanAt(prev_index) / 256);
} else
left_rate = this_rate * 2;
right_rate = 0.0F;
if (lis > segment_start) {
// Log the lis value within the last bucket now.
// Spread the remaining tally values as appropriate.
addToReportTally(histo_columns, lb, histo_span, lis, 1);
bucket_tally--;
}
// expect my slope to be negative
} else {
// since this is not first and not last, we know it has neighbors
segment_start = bucket_bounds[index];
int next_index = incrIndex(index);
int prev_index = decrIndex(index);
long end_of_span = bucket_bounds[next_index];
segment_quanta = (int) ((end_of_span - segment_start) / 256);
float this_rate = ((float) buckets[index] / segment_quanta);
float left_tally = (float) buckets[prev_index];
left_rate = left_tally / (spanAt(prev_index) / 256);
float right_tally = (float) buckets[next_index];
right_rate = right_tally / (spanAt(next_index) / 256);
if ((lis >= segment_start) && (lis < end_of_span)) {
// Log the lis value within the last bucket now.
// Spread the remaining tally values as appropriate.
addToReportTally(histo_columns, lb, histo_span, lis, 1);
bucket_tally--;
}
}
my_slope = (right_rate - left_rate) / (segment_quanta * 256);
float midpoint_time = segment_start + segment_quanta * 128;
my_intercept =
((float) bucket_tally) / segment_quanta - my_slope * midpoint_time;
if (bucket_tally < segment_quanta) {
// There are fewer tallied values than there are 256-microsecond segments
int pad;
long midpoint;
if (my_slope > 0.0) { // fill in from high end
pad = segment_quanta - bucket_tally;
midpoint = segment_start - 128 + pad * 256;
} else if (my_slope < 0.0) { // fill in from low end
pad = 0;
midpoint = segment_start + 128;
} else { // fill form middle
pad = (segment_quanta - bucket_tally) / 2;
midpoint = segment_start + 128 + pad * 256;
}
while (bucket_tally-- > 0) {
addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
midpoint += 256;
}
} else {
// There are more tallied values than there are 256-microsecond segments
if (my_intercept + (segment_start + 128) * my_slope < 0) {
// Rather than allowing the rate to go negative, form a triangle that
// slopes downward to the left, the enclosing rectangle holding twice
// the tally.
left_rate = 0.0F;
right_rate = (2 * (float) bucket_tally) / segment_quanta;
my_slope = (right_rate - left_rate) / (segment_quanta * 256);
// Since y = mx + b, calculate b = y_0 - m * x_0
// Rectangle holds bucket_tally * 2.
// Width of rectangle is segment_quanta.
// Height of rectangle is tally * 2 / segment_quanta.
// height at midpoint is (tally * 2 / segment_quanta) / 2, aka (tally / segment_quanta)
// y_0 is 0
// x_0 is segment_start
my_intercept = 0.0F - my_slope * segment_start;
} else if ((segment_start - 128 + 256 * segment_quanta) * my_slope
+ my_intercept < 0) {
// form a triangle that slopes downward to the right, the
// enclosing rectangle holding twice my tally.
left_rate = (2 * (float) bucket_tally) / segment_quanta;
right_rate = 0.0F;
my_slope = (right_rate - left_rate) / (segment_quanta * 256);
// Since y = mx + b, calculate b = y_0 - m * x_0
// y_0 is 0
// x_0 is segment_start + segment_quanta * 256
my_intercept = 0.0F - my_slope * (segment_start + segment_quanta * 256);
}
if (my_slope > 0) {
// fill from low to high
for (int j = 0; j < segment_quanta; j++) {
long quanta_midpoint = segment_start + 128 + 256 * j;
int quanta_contribution = java.lang.Math.round(my_intercept + quanta_midpoint * my_slope);
if (quanta_contribution > bucket_tally) {
quanta_contribution = bucket_tally;
}
addToReportTally(histo_columns, lb, histo_span, quanta_midpoint, quanta_contribution);
bucket_tally -= quanta_contribution;
}
while (bucket_tally > 0) {
long midpoint = segment_start + 128;
for (int j = 0; j < segment_quanta; j++) {
addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
midpoint += 256;
if (bucket_tally-- == 1)
break;
}
}
} else {
// fill from high to low
for (int j = segment_quanta - 1; j >= 0; j--) {
long quanta_midpoint = segment_start + 128 + 256 * j;
int quanta_contribution =
java.lang.Math.round(my_intercept + quanta_midpoint * my_slope);
if (quanta_contribution > bucket_tally) {
quanta_contribution = bucket_tally;
}
addToReportTally(histo_columns, lb, histo_span,
quanta_midpoint, quanta_contribution);
bucket_tally -= quanta_contribution;
}
// We distributed the tallies, but not all of them. Spread the remaining
// tallies "evenly".
while (bucket_tally > 0) {
long midpoint = segment_start - 128 + 256 * segment_quanta;
for (int j = 0; j < segment_quanta; j++) {
addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
midpoint -= 256;
if (bucket_tally-- == 1)
break;
}
}
}
}
}
index = incrIndex(index);
}
}