base::CPU: compute CPU family and model based on Intel and AMD manuals
Update how CPU family and model are computed for x86 architectures, using
the specifications in the Intel and AMD manuals.
In particular, the old code didn't take into account the extended family
when computing the display family. This computed an incorrect family for
AMD devices, because the common Intel microarchitectures have extended
family 0.
Also compute an extended model only for families where it is defined.
Moved the computation to a separate function, so it can be tested.
The family is used only in three places in the Chromium code base.
The use in chrome/browser/metrics/perf/cpu_identity.cc is what motivated
this change. The other two uses are used in logging.
BUG=b:128528055
Change-Id: I04de6c6cf22e0637246f89cfe0d1538bba194696
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1758824
Reviewed-by: Gabriel Marin <[email protected]>
Reviewed-by: Lei Zhang <[email protected]>
Commit-Queue: Gabriel Marin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#687903}
diff --git a/base/cpu_unittest.cc b/base/cpu_unittest.cc
index b6403af..09327e7 100644
--- a/base/cpu_unittest.cc
+++ b/base/cpu_unittest.cc
@@ -132,3 +132,46 @@
EXPECT_FALSE(base::Contains(cpu.cpu_brand(), '\0'));
EXPECT_FALSE(base::Contains(cpu.vendor_name(), '\0'));
}
+
+#if defined(ARCH_CPU_X86_FAMILY)
+// Tests that we compute the correct CPU family and model based on the vendor
+// and CPUID signature.
+TEST(CPU, X86FamilyAndModel) {
+ int family;
+ int model;
+ int ext_family;
+ int ext_model;
+
+ // Check with an Intel Skylake signature.
+ std::tie(family, model, ext_family, ext_model) =
+ base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x000406e3);
+ EXPECT_EQ(family, 6);
+ EXPECT_EQ(model, 78);
+ EXPECT_EQ(ext_family, 0);
+ EXPECT_EQ(ext_model, 4);
+
+ // Check with an Intel Airmont signature.
+ std::tie(family, model, ext_family, ext_model) =
+ base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x000406c2);
+ EXPECT_EQ(family, 6);
+ EXPECT_EQ(model, 76);
+ EXPECT_EQ(ext_family, 0);
+ EXPECT_EQ(ext_model, 4);
+
+ // Check with an Intel Prescott signature.
+ std::tie(family, model, ext_family, ext_model) =
+ base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x00000f31);
+ EXPECT_EQ(family, 15);
+ EXPECT_EQ(model, 3);
+ EXPECT_EQ(ext_family, 0);
+ EXPECT_EQ(ext_model, 0);
+
+ // Check with an AMD Excavator signature.
+ std::tie(family, model, ext_family, ext_model) =
+ base::internal::ComputeX86FamilyAndModel("AuthenticAMD", 0x00670f00);
+ EXPECT_EQ(family, 21);
+ EXPECT_EQ(model, 112);
+ EXPECT_EQ(ext_family, 6);
+ EXPECT_EQ(ext_model, 7);
+}
+#endif // defined(ARCH_CPU_X86_FAMILY)