blob: 476285ec1422d294507c9e83c24d6caf33df8dce [file] [log] [blame]
// Copyright 2015 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/perf/cpu_identity.h"
#include <algorithm> // for std::lower_bound()
#include <string.h>
#include "base/cpu.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
namespace internal {
const IntelUarchTableEntry kIntelUarchTable[] = {
// These were found on various sources on the Internet. Main ones are:
// http://instlatx64.atw.hu/ for CPUID to model name and
// http://www.cpu-world.com for model name to microarchitecture
{"06_09", "Banias"},
{"06_0D", "Dothan"},
{"06_0F", "Merom"},
{"06_16", "Merom"},
{"06_17", "Nehalem"},
{"06_1A", "Nehalem"},
{"06_1C", "Bonnell"}, // Atom
{"06_1D", "Nehalem"},
{"06_1E", "Nehalem"},
{"06_1F", "Nehalem"},
{"06_25", "Westmere"},
{"06_26", "Bonnell"}, // Atom
{"06_2A", "SandyBridge"},
{"06_2C", "Westmere"},
{"06_2D", "SandyBridge"},
{"06_2E", "Nehalem"},
{"06_2F", "Westmere"},
{"06_36", "Saltwell"}, // Atom
{"06_37", "Silvermont"},
{"06_3A", "IvyBridge"},
{"06_3C", "Haswell"},
{"06_3D", "Broadwell"},
{"06_3E", "IvyBridge"},
{"06_3F", "Haswell"},
{"06_45", "Haswell"},
{"06_46", "Haswell"},
{"06_47", "Broadwell"}, // Broadwell-H
{"06_4C", "Airmont"}, // Braswell
{"06_4E", "Skylake"},
{"06_56", "Broadwell"}, // Broadwell-DE
{"0F_03", "Prescott"},
{"0F_04", "Prescott"},
{"0F_06", "Presler"},
};
const IntelUarchTableEntry* kIntelUarchTableEnd =
kIntelUarchTable + arraysize(kIntelUarchTable);
bool IntelUarchTableCmp(const IntelUarchTableEntry& a,
const IntelUarchTableEntry& b) {
return strcmp(a.family_model, b.family_model) < 0;
}
} // namespace internal
CPUIdentity::CPUIdentity() : family(0), model(0) {}
CPUIdentity::~CPUIdentity() {}
std::string GetIntelUarch(const CPUIdentity& cpuid) {
if (cpuid.vendor != "GenuineIntel")
return std::string(); // Non-Intel
std::string family_model =
base::StringPrintf("%02X_%02X", cpuid.family, cpuid.model);
const internal::IntelUarchTableEntry search_elem = {family_model.c_str(), ""};
const auto bound = std::lower_bound(
internal::kIntelUarchTable, internal::kIntelUarchTableEnd,
search_elem, internal::IntelUarchTableCmp);
if (bound->family_model != family_model)
return std::string(); // Unknown uarch
return bound->uarch;
}
CPUIdentity GetCPUIdentity() {
CPUIdentity result = {};
result.arch = base::SysInfo::OperatingSystemArchitecture();
base::CPU cpuid;
result.vendor = cpuid.vendor_name();
result.family = cpuid.family();
result.model = cpuid.model();
result.model_name = cpuid.cpu_brand();
return result;
}
std::string SimplifyCPUModelName(const std::string& model_name) {
std::string result = model_name;
std::replace(result.begin(), result.end(), ' ', '-');
base::ReplaceSubstringsAfterOffset(&result, 0, "(R)", "");
return base::ToLowerASCII(result);
}