Commit 85acecb3 authored by chrisha@chromium.org's avatar chrisha@chromium.org

Make a pre-read A/B field-trial

This CL disables/enables the Windows pre-read optimization based on a client-side coin-toss. The base::FieldTrial mechanism has not been used as it is not available until *after* chrome.dll is loaded, and this needs to occur before.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/7508034

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95579 0039d316-1c4b-4281-b951-d872f2087c98
parent f410d614
...@@ -11,10 +11,11 @@ ...@@ -11,10 +11,11 @@
#include "base/file_util.h" #include "base/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/win/registry.h" #include "base/rand_util.h" // For PreReadExperiment.
#include "base/string_util.h" #include "base/string_util.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "base/version.h" #include "base/version.h"
#include "base/win/registry.h"
#include "chrome/app/breakpad_win.h" #include "chrome/app/breakpad_win.h"
#include "chrome/app/client_util.h" #include "chrome/app/client_util.h"
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
...@@ -126,6 +127,9 @@ HMODULE LoadChromeWithDirectory(std::wstring* dir) { ...@@ -126,6 +127,9 @@ HMODULE LoadChromeWithDirectory(std::wstring* dir) {
DWORD pre_read_step_size = kStepSize; DWORD pre_read_step_size = kStepSize;
DWORD pre_read = 1; DWORD pre_read = 1;
// TODO(chrisha): This path should not be ChromeFrame specific, and it
// should not be hard-coded with 'Google' in the path. Rather, it should
// use the product name.
base::win::RegKey key(HKEY_CURRENT_USER, L"Software\\Google\\ChromeFrame", base::win::RegKey key(HKEY_CURRENT_USER, L"Software\\Google\\ChromeFrame",
KEY_QUERY_VALUE); KEY_QUERY_VALUE);
if (key.Valid()) { if (key.Valid()) {
...@@ -134,6 +138,26 @@ HMODULE LoadChromeWithDirectory(std::wstring* dir) { ...@@ -134,6 +138,26 @@ HMODULE LoadChromeWithDirectory(std::wstring* dir) {
key.ReadValueDW(L"PreRead", &pre_read); key.ReadValueDW(L"PreRead", &pre_read);
key.Close(); key.Close();
} }
// The Syzygy project is a competing optimization technique. Part of the
// evaluation consists of an A/B experiment. As a baseline, we wish to
// evaluate startup time with preread enabled and disabled. We can't use
// base::FieldTrial as this only exists *after* chrome.dll is loaded. We
// override the registry setting with a coin-toss for the duration of the
// experiment.
// NOTE: This experiment is intended for Canary and Dev only, and should be
// removed from any branch heading out to beta and beyond!
pre_read = base::RandInt(0, 1);
DCHECK(pre_read == 0 || pre_read == 1);
// We communicate the coin-toss result via a side-channel
// (environment variable) to chrome.dll. This ensures that chrome.dll
// only reports experiment results if it has been launched by a
// chrome.exe that is actually running the experiment.
scoped_ptr<base::Environment> env(base::Environment::Create());
DCHECK(env.get() != NULL);
env->SetVar("CHROME_PRE_READ_EXPERIMENT", pre_read ? "1" : "0");
if (pre_read) { if (pre_read) {
TRACE_EVENT_BEGIN_ETW("PreReadImage", 0, ""); TRACE_EVENT_BEGIN_ETW("PreReadImage", 0, "");
file_util::PreReadImage(dir->c_str(), pre_read_size, pre_read_step_size); file_util::PreReadImage(dir->c_str(), pre_read_size, pre_read_step_size);
......
...@@ -165,6 +165,7 @@ ...@@ -165,6 +165,7 @@
#include <commctrl.h> #include <commctrl.h>
#include <shellapi.h> #include <shellapi.h>
#include "base/environment.h" // For PreRead experiment.
#include "base/win/scoped_com_initializer.h" #include "base/win/scoped_com_initializer.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "chrome/browser/browser_trial.h" #include "chrome/browser/browser_trial.h"
...@@ -227,6 +228,48 @@ namespace net { ...@@ -227,6 +228,48 @@ namespace net {
class NetLog; class NetLog;
} // namespace net } // namespace net
// This code is specific to the Windows-only PreReadExperiment field-trial.
static void AddPreReadHistogramTime(const char* name, base::TimeDelta time) {
const base::TimeDelta kMin(base::TimeDelta::FromMilliseconds(1));
const base::TimeDelta kMax(base::TimeDelta::FromHours(1));
static const size_t kBuckets(100);
// FactoryTimeGet will always return a pointer to the same histogram object,
// keyed on its name. There's no need for us to store it explicitly anywhere.
base::Histogram* counter = base::Histogram::FactoryTimeGet(
name, kMin, kMax, kBuckets, base::Histogram::kUmaTargetedHistogramFlag);
counter->AddTime(time);
}
// This code is specific to the Windows-only PreReadExperiment field-trial.
void RecordPreReadExperimentTime(const char* name, base::TimeDelta time) {
DCHECK(name != NULL);
// This gets called with different histogram names, so we don't want to use
// the UMA_HISTOGRAM_CUSTOM_TIMES macro--it uses a static variable, and the
// first call wins.
AddPreReadHistogramTime(name, time);
#if defined(OS_WIN)
static const char kEnvVar[] = "CHROME_PRE_READ_EXPERIMENT";
// The pre-read experiment is Windows specific.
scoped_ptr<base::Environment> env(base::Environment::Create());
DCHECK(env.get() != NULL);
// Only record the sub-histogram result if the experiment is running
// (environment variable is set, and valid).
std::string pre_read;
if (env->GetVar(kEnvVar, &pre_read) && (pre_read == "0" || pre_read == "1")) {
std::string uma_name(name);
uma_name += "_PreRead";
uma_name += pre_read == "1" ? "Enabled" : "Disabled";
AddPreReadHistogramTime(uma_name.c_str(), time);
}
#endif
}
// BrowserMainParts ------------------------------------------------------------ // BrowserMainParts ------------------------------------------------------------
BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
...@@ -2026,8 +2069,8 @@ int BrowserMain(const MainFunctionParams& parameters) { ...@@ -2026,8 +2069,8 @@ int BrowserMain(const MainFunctionParams& parameters) {
if (pool) if (pool)
pool->Recycle(); pool->Recycle();
UMA_HISTOGRAM_MEDIUM_TIMES("Startup.BrowserOpenTabs", RecordPreReadExperimentTime("Startup.BrowserOpenTabs",
base::TimeTicks::Now() - browser_open_start); base::TimeTicks::Now() - browser_open_start);
// TODO(mad): Move this call in a proper place on CrOS. // TODO(mad): Move this call in a proper place on CrOS.
// http://crosbug.com/17687 // http://crosbug.com/17687
......
...@@ -205,4 +205,11 @@ void WarnAboutMinimumSystemRequirements(); ...@@ -205,4 +205,11 @@ void WarnAboutMinimumSystemRequirements();
// the UMA histogram |metric_name|. // the UMA histogram |metric_name|.
void RecordBrowserStartupTime(); void RecordBrowserStartupTime();
// Records a Startup category value to an UMA histogram in the context of the
// PreReadExperiment field-trial. This will also report to the appropriate
// Startup.HistogramName_PreRead(Enabled|Disabled) histogram as appropriate.
// This is only called from OS_WIN specific code, so the implementation is
// in browser_main_win.cc. This is a Windows specific experiment.
void RecordPreReadExperimentTime(const char* name, base::TimeDelta time);
#endif // CHROME_BROWSER_BROWSER_MAIN_H_ #endif // CHROME_BROWSER_BROWSER_MAIN_H_
...@@ -90,12 +90,9 @@ void RecordBrowserStartupTime() { ...@@ -90,12 +90,9 @@ void RecordBrowserStartupTime() {
::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore, ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore,
&ignore); &ignore);
base::TimeDelta elapsed_from_startup = RecordPreReadExperimentTime(
base::Time::Now() - base::Time::FromFileTime(creation_time); "Startup.BrowserMessageLoopStartTime",
base::Time::Now() - base::Time::FromFileTime(creation_time));
// Record the time to present in a histogram.
UMA_HISTOGRAM_MEDIUM_TIMES("Startup.BrowserMessageLoopStartTime",
elapsed_from_startup);
} }
int AskForUninstallConfirmation() { int AskForUninstallConfirmation() {
......
...@@ -283,6 +283,7 @@ ...@@ -283,6 +283,7 @@
'browser/browser_about_handler.cc', 'browser/browser_about_handler.cc',
'browser/browser_about_handler.h', 'browser/browser_about_handler.h',
'browser/browser_main.cc', 'browser/browser_main.cc',
'browser/browser_main.h',
'browser/browser_main_gtk.cc', 'browser/browser_main_gtk.cc',
'browser/browser_main_gtk.h', 'browser/browser_main_gtk.h',
'browser/browser_main_mac.mm', 'browser/browser_main_mac.mm',
......
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