Commit 76751481 authored by Siddhartha's avatar Siddhartha Committed by Commit Bot

Sampling profiler: Make option to sample more leniently

In the current profiler, if a single sample takes too long then the
sampling tasks get crowded and stops the main thread from running for
a long time. But usually the slowest part is the stack copying for
which the main thread is paused anyway. So, it is ok to take next sample
after the interval time after previous sample completes, instead of
strictly sampling every interval.

BUG=859260

Change-Id: Ib0671b1f465f5cf98caa01aeac615648b24a1cf4
Reviewed-on: https://chromium-review.googlesource.com/1234841
Commit-Queue: Siddhartha S <ssid@chromium.org>
Reviewed-by: default avatarXi Cheng <chengx@chromium.org>
Reviewed-by: default avatarAlexei Filippov <alph@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593375}
parent 43a86d27
...@@ -519,11 +519,8 @@ void StackSamplingProfiler::SamplingThread::RecordSampleTask( ...@@ -519,11 +519,8 @@ void StackSamplingProfiler::SamplingThread::RecordSampleTask(
// Schedule the next sample recording if there is one. // Schedule the next sample recording if there is one.
if (++collection->sample_count < collection->params.samples_per_profile) { if (++collection->sample_count < collection->params.samples_per_profile) {
// This will keep a consistent average interval between samples but will if (!collection->params.keep_consistent_sampling_interval)
// result in constant series of acquisitions, thus nearly locking out the collection->next_sample_time = Time::Now();
// target thread, if the interval is smaller than the time it takes to
// actually acquire the sample. Anything sampling that quickly is going
// to be a problem anyway so don't worry about it.
collection->next_sample_time += collection->params.sampling_interval; collection->next_sample_time += collection->params.sampling_interval;
bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask( bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask(
FROM_HERE, FROM_HERE,
......
...@@ -79,6 +79,16 @@ class BASE_EXPORT StackSamplingProfiler { ...@@ -79,6 +79,16 @@ class BASE_EXPORT StackSamplingProfiler {
// Interval between samples during a sampling profile. This is the desired // Interval between samples during a sampling profile. This is the desired
// duration from the start of one sample to the start of the next sample. // duration from the start of one sample to the start of the next sample.
TimeDelta sampling_interval = TimeDelta::FromMilliseconds(100); TimeDelta sampling_interval = TimeDelta::FromMilliseconds(100);
// When true, keeps the average sampling interval = |sampling_interval|,
// irrespective of how long each sample takes. If a sample takes too long,
// keeping the interval constant will lock out the sampled thread. When
// false, sample is created with an interval of |sampling_interval|,
// excluding the time taken by a sample. The metrics collected will not be
// accurate, since sampling could take arbitrary amount of time, but makes
// sure that the sampled thread gets at least the interval amount of time to
// run between samples.
bool keep_consistent_sampling_interval = true;
}; };
// The ProfileBuilder interface allows the user to record profile information // The ProfileBuilder interface allows the user to record profile information
......
...@@ -39,7 +39,8 @@ constexpr const double kFractionOfExecutionTimeToSample = 0.02; ...@@ -39,7 +39,8 @@ constexpr const double kFractionOfExecutionTimeToSample = 0.02;
constexpr struct StackSamplingProfiler::SamplingParams kSamplingParams = { constexpr struct StackSamplingProfiler::SamplingParams kSamplingParams = {
/* initial_delay= */ base::TimeDelta::FromMilliseconds(0), /* initial_delay= */ base::TimeDelta::FromMilliseconds(0),
/* samples_per_profile= */ 300, /* samples_per_profile= */ 300,
/* sampling_interval= */ base::TimeDelta::FromMilliseconds(100)}; /* sampling_interval= */ base::TimeDelta::FromMilliseconds(100),
/* keep_consistent_sampling_interval= */ true};
CallStackProfileParams::Process GetProcess() { CallStackProfileParams::Process GetProcess() {
const base::CommandLine* command_line = const base::CommandLine* command_line =
......
...@@ -137,6 +137,10 @@ void TracingSamplerProfiler::OnTraceLogEnabled() { ...@@ -137,6 +137,10 @@ void TracingSamplerProfiler::OnTraceLogEnabled() {
base::StackSamplingProfiler::SamplingParams params; base::StackSamplingProfiler::SamplingParams params;
params.samples_per_profile = std::numeric_limits<int>::max(); params.samples_per_profile = std::numeric_limits<int>::max();
params.sampling_interval = base::TimeDelta::FromMilliseconds(50); params.sampling_interval = base::TimeDelta::FromMilliseconds(50);
// If the sampled thread is stopped for too long for sampling then it is ok to
// get next sample at a later point of time. We do not want very accurate
// metrics when looking at traces.
params.keep_consistent_sampling_interval = false;
// Create and start the stack sampling profiler. // Create and start the stack sampling profiler.
#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ #if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
......
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