Commit 5ec20588 authored by Gabriel Charette's avatar Gabriel Charette Committed by Commit Bot

[Metrics] Introduce High-resolution timing histograms/macros.

Migrated two metrics to use new APIs and flagged other identified
histograms' descriptions to highlight issue on dashboards (I will
email relevant owners after this lands).
Relevant metrics list extracted from https://crbug.com/807615#c19

R=asvitkine@chromium.org, fdoray@chromium.org

Bug: 807615
Change-Id: I84f0f8fb5ca7fd3c5b43ba7209693b89928ade07
Reviewed-on: https://chromium-review.googlesource.com/1062830
Commit-Queue: Gabriel Charette <gab@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarAlexei Svitkine <asvitkine@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560704}
parent 44f61c43
...@@ -268,6 +268,16 @@ HistogramBase* Histogram::FactoryTimeGet(const std::string& name, ...@@ -268,6 +268,16 @@ HistogramBase* Histogram::FactoryTimeGet(const std::string& name,
flags); flags);
} }
HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const std::string& name,
TimeDelta minimum,
TimeDelta maximum,
uint32_t bucket_count,
int32_t flags) {
return FactoryGet(name, static_cast<Sample>(minimum.InMicroseconds()),
static_cast<Sample>(maximum.InMicroseconds()), bucket_count,
flags);
}
HistogramBase* Histogram::FactoryGet(const char* name, HistogramBase* Histogram::FactoryGet(const char* name,
Sample minimum, Sample minimum,
Sample maximum, Sample maximum,
...@@ -285,6 +295,15 @@ HistogramBase* Histogram::FactoryTimeGet(const char* name, ...@@ -285,6 +295,15 @@ HistogramBase* Histogram::FactoryTimeGet(const char* name,
flags); flags);
} }
HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const char* name,
TimeDelta minimum,
TimeDelta maximum,
uint32_t bucket_count,
int32_t flags) {
return FactoryMicrosecondsTimeGet(std::string(name), minimum, maximum,
bucket_count, flags);
}
std::unique_ptr<HistogramBase> Histogram::PersistentCreate( std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
const char* name, const char* name,
Sample minimum, Sample minimum,
......
...@@ -125,10 +125,15 @@ class BASE_EXPORT Histogram : public HistogramBase { ...@@ -125,10 +125,15 @@ class BASE_EXPORT Histogram : public HistogramBase {
base::TimeDelta maximum, base::TimeDelta maximum,
uint32_t bucket_count, uint32_t bucket_count,
int32_t flags); int32_t flags);
static HistogramBase* FactoryMicrosecondsTimeGet(const std::string& name,
// Overloads of the above two functions that take a const char* |name| param, base::TimeDelta minimum,
// to avoid code bloat from the std::string constructor being inlined into base::TimeDelta maximum,
// call sites. uint32_t bucket_count,
int32_t flags);
// Overloads of the above functions that take a const char* |name| param, to
// avoid code bloat from the std::string constructor being inlined into call
// sites.
static HistogramBase* FactoryGet(const char* name, static HistogramBase* FactoryGet(const char* name,
Sample minimum, Sample minimum,
Sample maximum, Sample maximum,
...@@ -139,6 +144,11 @@ class BASE_EXPORT Histogram : public HistogramBase { ...@@ -139,6 +144,11 @@ class BASE_EXPORT Histogram : public HistogramBase {
base::TimeDelta maximum, base::TimeDelta maximum,
uint32_t bucket_count, uint32_t bucket_count,
int32_t flags); int32_t flags);
static HistogramBase* FactoryMicrosecondsTimeGet(const char* name,
base::TimeDelta minimum,
base::TimeDelta maximum,
uint32_t bucket_count,
int32_t flags);
// Create a histogram using data in persistent storage. // Create a histogram using data in persistent storage.
static std::unique_ptr<HistogramBase> PersistentCreate( static std::unique_ptr<HistogramBase> PersistentCreate(
......
...@@ -112,10 +112,18 @@ void HistogramBase::AddKiB(Sample value, int count) { ...@@ -112,10 +112,18 @@ void HistogramBase::AddKiB(Sample value, int count) {
AddScaled(value, count, 1024); AddScaled(value, count, 1024);
} }
void HistogramBase::AddTime(const TimeDelta& time) { void HistogramBase::AddTimeMillisecondsGranularity(const TimeDelta& time) {
Add(static_cast<Sample>(time.InMilliseconds())); Add(static_cast<Sample>(time.InMilliseconds()));
} }
void HistogramBase::AddTimeMicrosecondsGranularity(const TimeDelta& time) {
// Intentionally drop high-resolution reports on clients with low-resolution
// clocks. High-resolution metrics cannot make use of low-resolution data and
// reporting it merely adds noise to the metric. https://crbug.com/807615#c16
if (TimeTicks::IsHighResolution())
Add(static_cast<Sample>(time.InMicroseconds()));
}
void HistogramBase::AddBoolean(bool value) { void HistogramBase::AddBoolean(bool value) {
Add(value ? 1 : 0); Add(value ? 1 : 0);
} }
......
...@@ -189,8 +189,12 @@ class BASE_EXPORT HistogramBase { ...@@ -189,8 +189,12 @@ class BASE_EXPORT HistogramBase {
void AddKilo(Sample value, int count); // scale=1000 void AddKilo(Sample value, int count); // scale=1000
void AddKiB(Sample value, int count); // scale=1024 void AddKiB(Sample value, int count); // scale=1024
// 2 convenient functions that call Add(Sample). // Convenient functions that call Add(Sample).
void AddTime(const TimeDelta& time); void AddTime(const TimeDelta& time) { AddTimeMillisecondsGranularity(time); }
void AddTimeMillisecondsGranularity(const TimeDelta& time);
// Note: AddTimeMicrosecondsGranularity() drops the report if this client
// doesn't have a high-resolution clock.
void AddTimeMicrosecondsGranularity(const TimeDelta& time);
void AddBoolean(bool value); void AddBoolean(bool value);
virtual void AddSamples(const HistogramSamples& samples) = 0; virtual void AddSamples(const HistogramSamples& samples) = 0;
......
...@@ -71,7 +71,7 @@ void UmaHistogramCustomTimes(const std::string& name, ...@@ -71,7 +71,7 @@ void UmaHistogramCustomTimes(const std::string& name,
int buckets) { int buckets) {
HistogramBase* histogram = Histogram::FactoryTimeGet( HistogramBase* histogram = Histogram::FactoryTimeGet(
name, min, max, buckets, HistogramBase::kUmaTargetedHistogramFlag); name, min, max, buckets, HistogramBase::kUmaTargetedHistogramFlag);
histogram->AddTime(sample); histogram->AddTimeMillisecondsGranularity(sample);
} }
void UmaHistogramTimes(const std::string& name, TimeDelta sample) { void UmaHistogramTimes(const std::string& name, TimeDelta sample) {
......
...@@ -178,7 +178,8 @@ ...@@ -178,7 +178,8 @@
// Sample usage: // Sample usage:
// UMA_HISTOGRAM_TIMES("My.Timing.Histogram", time_delta); // UMA_HISTOGRAM_TIMES("My.Timing.Histogram", time_delta);
// Short timings - up to 10 seconds. // Short timings - up to 10 seconds. For high-resolution (microseconds) timings,
// see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES.
#define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
name, sample, base::TimeDelta::FromMilliseconds(1), \ name, sample, base::TimeDelta::FromMilliseconds(1), \
base::TimeDelta::FromSeconds(10), 50) base::TimeDelta::FromSeconds(10), 50)
...@@ -206,10 +207,32 @@ ...@@ -206,10 +207,32 @@
// Sample usage: // Sample usage:
// UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", time_delta, // UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", time_delta,
// base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); // base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100);
#define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ STATIC_HISTOGRAM_POINTER_BLOCK( \
base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ name, AddTimeMillisecondsGranularity(sample), \
base::HistogramBase::kUmaTargetedHistogramFlag)) base::Histogram::FactoryTimeGet( \
name, min, max, bucket_count, \
base::HistogramBase::kUmaTargetedHistogramFlag))
// Same as UMA_HISTOGRAM_CUSTOM_TIMES but reports |sample| in microseconds,
// dropping the report if this client doesn't have a high-resolution clock.
//
// Note: dropping reports on clients with low-resolution clocks means these
// reports will be biased to a portion of the population on Windows. See
// Windows.HasHighResolutionTimeTicks for the affected sample.
//
// Sample usage:
// UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
// "High.Resolution.TimingMicroseconds.Histogram", time_delta,
// base::TimeDelta::FromMicroseconds(1),
// base::TimeDelta::FromMilliseconds(10), 100);
#define UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(name, sample, min, max, \
bucket_count) \
STATIC_HISTOGRAM_POINTER_BLOCK( \
name, AddTimeMicrosecondsGranularity(sample), \
base::Histogram::FactoryMicrosecondsTimeGet( \
name, min, max, bucket_count, \
base::HistogramBase::kUmaTargetedHistogramFlag))
// Scoped class which logs its time on this earth as a UMA statistic. This is // Scoped class which logs its time on this earth as a UMA statistic. This is
// recommended for when you want a histogram which measures the time it takes // recommended for when you want a histogram which measures the time it takes
......
...@@ -64,10 +64,11 @@ ...@@ -64,10 +64,11 @@
name, sample, base::TimeDelta::FromMilliseconds(1), \ name, sample, base::TimeDelta::FromMilliseconds(1), \
base::TimeDelta::FromSeconds(10), 50) base::TimeDelta::FromSeconds(10), 50)
#define LOCAL_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ #define LOCAL_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ STATIC_HISTOGRAM_POINTER_BLOCK( \
base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ name, AddTimeMillisecondsGranularity(sample), \
base::HistogramBase::kNoFlags)) base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
base::HistogramBase::kNoFlags))
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Memory histograms. // Memory histograms.
......
...@@ -85,8 +85,7 @@ HistogramBase* GetLatencyHistogram(StringPiece histogram_name, ...@@ -85,8 +85,7 @@ HistogramBase* GetLatencyHistogram(StringPiece histogram_name,
DCHECK(!histogram_name.empty()); DCHECK(!histogram_name.empty());
DCHECK(!histogram_label.empty()); DCHECK(!histogram_label.empty());
DCHECK(!task_type_suffix.empty()); DCHECK(!task_type_suffix.empty());
// Mimics the UMA_HISTOGRAM_TIMES macro except we don't specify bounds with // Mimics the UMA_HISTOGRAM_HIGH_RESOLUTION_CUSTOM_TIMES macro. The minimums
// TimeDeltas as FactoryTimeGet assumes millisecond granularity. The minimums
// and maximums were chosen to place the 1ms mark at around the 70% range // and maximums were chosen to place the 1ms mark at around the 70% range
// coverage for buckets giving us good info for tasks that have a latency // coverage for buckets giving us good info for tasks that have a latency
// below 1ms (most of them) and enough info to assess how bad the latency is // below 1ms (most of them) and enough info to assess how bad the latency is
...@@ -94,8 +93,10 @@ HistogramBase* GetLatencyHistogram(StringPiece histogram_name, ...@@ -94,8 +93,10 @@ HistogramBase* GetLatencyHistogram(StringPiece histogram_name,
const std::string histogram = JoinString( const std::string histogram = JoinString(
{"TaskScheduler", histogram_name, histogram_label, task_type_suffix}, {"TaskScheduler", histogram_name, histogram_label, task_type_suffix},
"."); ".");
return Histogram::FactoryGet(histogram, 1, 20000, 50, return Histogram::FactoryMicrosecondsTimeGet(
HistogramBase::kUmaTargetedHistogramFlag); histogram, TimeDelta::FromMicroseconds(1),
TimeDelta::FromMilliseconds(20), 50,
HistogramBase::kUmaTargetedHistogramFlag);
} }
// Upper bound for the // Upper bound for the
...@@ -461,7 +462,7 @@ void TaskTracker::RecordLatencyHistogram( ...@@ -461,7 +462,7 @@ void TaskTracker::RecordLatencyHistogram(
[task_traits.may_block() || task_traits.with_base_sync_primitives() [task_traits.may_block() || task_traits.with_base_sync_primitives()
? 1 ? 1
: 0] : 0]
->Add(task_latency.InMicroseconds()); ->AddTimeMicrosecondsGranularity(task_latency);
} }
void TaskTracker::RunOrSkipTask(Task task, void TaskTracker::RunOrSkipTask(Task task,
......
...@@ -22,11 +22,13 @@ ...@@ -22,11 +22,13 @@
histogram_pointer->histogram_add_method_invocation; \ histogram_pointer->histogram_add_method_invocation; \
} while (0) } while (0)
#define UMA_HISTOGRAM_CUSTOM_TIMES_NO_CACHE( \ #define UMA_HISTOGRAM_CUSTOM_TIMES_NO_CACHE(name, sample, min, max, \
name, sample, min, max, bucket_count) \ bucket_count) \
STATIC_HISTOGRAM_POINTER_BLOCK_NO_CACHE(name, AddTime(sample), \ STATIC_HISTOGRAM_POINTER_BLOCK_NO_CACHE( \
base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ name, AddTimeMillisecondsGranularity(sample), \
base::Histogram::kUmaTargetedHistogramFlag)) base::Histogram::FactoryTimeGet( \
name, min, max, bucket_count, \
base::Histogram::kUmaTargetedHistogramFlag))
#define UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(name, sample, min, max, \ #define UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(name, sample, min, max, \
bucket_count, count) \ bucket_count, count) \
......
This diff is collapsed.
...@@ -182,10 +182,11 @@ ComputeNativeWindowOcclusionStatusImpl( ...@@ -182,10 +182,11 @@ ComputeNativeWindowOcclusionStatusImpl(
if (window_evaluator.HasAtLeastOneVisibleWindow()) if (window_evaluator.HasAtLeastOneVisibleWindow())
iterator->Iterate(&window_evaluator); iterator->Iterate(&window_evaluator);
// Record the duration of the call to ComputeNativeWindowOcclusionStatus(). UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
base::TimeDelta duration = base::TimeTicks::Now() - calculation_start_time; "Windows.ComputeNativeWindowOcclusionTime",
UMA_HISTOGRAM_COUNTS_10M("Windows.ComputeNativeWindowOcclusionTime", base::TimeTicks::Now() - calculation_start_time,
duration.InMicroseconds()); base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
50);
return window_evaluator.TakeResult(); return window_evaluator.TakeResult();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment