diff options
author | simonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 19:46:05 +0000 |
---|---|---|
committer | simonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 19:46:05 +0000 |
commit | aa31281d74a2d0a4a37185ec2888d06eb726eb16 (patch) | |
tree | 96a9403e28a301d040c272af6e28fbac354ca345 /chrome/browser/metrics/time_ticks_experiment_win.cc | |
parent | e98a235bf3764de80423b0854b84de76c81f1778 (diff) | |
download | chromium_src-aa31281d74a2d0a4a37185ec2888d06eb726eb16.zip chromium_src-aa31281d74a2d0a4a37185ec2888d06eb726eb16.tar.gz chromium_src-aa31281d74a2d0a4a37185ec2888d06eb726eb16.tar.bz2 |
Create a field trial to test if we can detect good QPC implementations.
We'd like to use QPC (TimeTicks::HighResNow) for all uses of TimeTicks. It's
likely this will only work on some subset of Windows systems. This field trial
is meant to determine if an implementation is good and if our heuristics are
able to detect a good implementation.
This particular CL checks for an Intel CPU parameter that indicates rdtsc is
consistently incremented. Firefox uses the same check. I hope to determine that
this is in fact correct and on which versions of Windows QPC calls rdtsc
directly.
We can add more heuristics later.
BUG=158234
Review URL: https://chromiumcodereview.appspot.com/13583007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197431 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/metrics/time_ticks_experiment_win.cc')
-rw-r--r-- | chrome/browser/metrics/time_ticks_experiment_win.cc | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/chrome/browser/metrics/time_ticks_experiment_win.cc b/chrome/browser/metrics/time_ticks_experiment_win.cc new file mode 100644 index 0000000..3e1250b --- /dev/null +++ b/chrome/browser/metrics/time_ticks_experiment_win.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/metrics/time_ticks_experiment_win.h" + +#if defined(OS_WIN) + +#include "base/cpu.h" +#include "base/metrics/histogram.h" +#include "base/win/windows_version.h" + +#include <windows.h> + +namespace chrome { + +namespace { + +const int kNumIterations = 1000; + +} // anonymous namespace + +void CollectTimeTicksStats() { + // This bit is supposed to indicate that rdtsc is safe across cores. If so, we + // can use QPC as long as it uses rdtsc. + // TODO(simonjam): We should look for other signals that QPC might be safe and + // test them out here. + base::CPU cpu; + UMA_HISTOGRAM_BOOLEAN("WinTimeTicks.NonStopTsc", + cpu.has_non_stop_time_stamp_counter()); + if (!cpu.has_non_stop_time_stamp_counter()) { + return; + } + + DWORD_PTR default_mask; + DWORD_PTR system_mask; + if (!GetProcessAffinityMask(GetCurrentProcess(), + &default_mask, &system_mask)) { + return; + } + + SYSTEM_INFO sys_info; + GetSystemInfo(&sys_info); + DWORD num_cores = sys_info.dwNumberOfProcessors; + DWORD current_core = 0; + bool failed_to_change_cores = false; + + base::win::OSInfo* info = base::win::OSInfo::GetInstance(); + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.VersionTotal", info->version(), + base::win::VERSION_WIN_LAST); + + LARGE_INTEGER qpc_frequency; + QueryPerformanceFrequency(&qpc_frequency); + + int min_delta = 1e9; + LARGE_INTEGER qpc_last; + QueryPerformanceCounter(&qpc_last); + for (int i = 0; i < kNumIterations; ++i) { + LARGE_INTEGER qpc_now; + QueryPerformanceCounter(&qpc_now); + int delta = static_cast<int>(qpc_now.QuadPart - qpc_last.QuadPart); + if (delta != 0) { + min_delta = std::min(min_delta, delta); + } + qpc_last = qpc_now; + + if (num_cores > 1 && (i % 100) == 0) { + ++current_core; + if (current_core > num_cores) { + current_core = 0; + } + if (!SetThreadAffinityMask(GetCurrentThread(), 1 << current_core)) { + failed_to_change_cores = true; + break; + } + } + } + + if (num_cores > 1) { + SetThreadAffinityMask(GetCurrentThread(), default_mask); + if (failed_to_change_cores) { + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.FailedToChangeCores", + info->version(), base::win::VERSION_WIN_LAST); + return; + } + } + + if (min_delta < 0) { + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.TickedBackwards", info->version(), + base::win::VERSION_WIN_LAST); + return; + } + + int min_delta_ns = static_cast<int>( + min_delta * (1e9 / qpc_frequency.QuadPart)); + UMA_HISTOGRAM_CUSTOM_COUNTS("WinTimeTicks.MinResolutionNanoseconds", + min_delta_ns, 1, 1000000, 50); + + bool success = min_delta_ns <= 10000; + if (success) { + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.VersionSuccessful", + info->version(), base::win::VERSION_WIN_LAST); + } +} + +} // namespace chrome + +#endif // defined(OS_WIN) |