internal static string GetCleanCpuName(CpuVendor vendor, string name) { switch (vendor) { case CpuVendor.Intel: { // Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz var matches = _cpuIntelRegex.Match(name); if (matches.Success) { return($"Core {matches.Groups[1].Value}"); } } break; case CpuVendor.AMD: { // AMD Ryzen 7 2700X Eight-Core Processor -> Ryzen 7 2700X var matches = _cpuRyzenRegex.Match(name); if (matches.Success) { return($"Ryzen {matches.Groups[1].Value}"); } } break; } // Eh, couldn't improve it return(name); }
public VendorInfo(CpuVendor vendorId, char[] text) { Contract.Requires(text != null); _vendorId = vendorId; _text = text; }
internal CpuInfo(CpuVendor vendor, string name, int clockSpeed, int threadCount) { Vendor = vendor; Name = HardwareDetector.GetCleanCpuName(vendor, name); ThreadCount = threadCount; ClockSpeed = clockSpeed; }
/// <summary>Compares for equality with another <see cref="CpuVendor" /> object.</summary> /// <remarks>Comparison is performed by value.</remarks> public bool Equals(CpuVendor other) { return(this.id == other.id); }
/// <summary>Compares for equality with another <see cref="CpuVendor" /> object.</summary> /// <remarks>Comparison is performed by value.</remarks> public bool Equals(CpuVendor other) { return this.id == other.id; }
private void DetectCpuInfo() { _vendor = "Unknown"; _numberOfProcessors = Environment.ProcessorCount; byte[] vendor = new byte[12]; if (Util.IsX86 || Util.IsX64) { uint a; uint eax; uint ebx; uint ecx; uint edx; // Get vendor string eax = 0; CpuIdMethod cpuId = CpuId; cpuId(ref eax, out ebx, out ecx, out edx); BitConverter.GetBytes(ebx).CopyTo(vendor, 0); BitConverter.GetBytes(edx).CopyTo(vendor, 4); BitConverter.GetBytes(ecx).CopyTo(vendor, 8); for (a = 0; a < 3; a++) { //if (memcmp(vendor, _vendorInfo[a].text, 12) == 0) if (vendor.SequenceEqual(_vendorInfo[a].Text.Select(i => (byte)i))) { _vendorId = _vendorInfo[a].Vendor; _vendor = new string(_vendorInfo[a].Text.ToArray()); break; } } // get feature flags in ecx/edx, and family/model in eax eax = 1; CpuId(ref eax, out ebx, out ecx, out edx); // family and model fields _family = (int)(eax >> 8) & 0x0F; _model = (int)(eax >> 4) & 0x0F; _stepping = (int)(eax) & 0x0F; // use extended family and model fields if (_family == 0x0F) { _family += (int)((eax >> 20) & 0xFF); _model += (int)(((eax >> 16) & 0x0F) << 4); } _x86ExtendedInfo.ProcessorType = (int)((eax >> 12) & 0x03); _x86ExtendedInfo.BrandIndex = (int)((ebx) & 0xFF); _x86ExtendedInfo.FlushCacheLineSize = (int)((ebx >> 8) & 0xFF) * 8; _x86ExtendedInfo.MaxLogicalProcessors = (int)((ebx >> 16) & 0xFF); _x86ExtendedInfo.ApicPhysicalId = (int)((ebx >> 24) & 0xFF); if ((ecx & 0x00000001U) != 0) _features |= CpuFeatures.SSE3; if ((ecx & 0x00000002U) != 0) _features |= CpuFeatures.PCLMULDQ; if ((ecx & 0x00000008U) != 0) _features |= CpuFeatures.MONITOR_MWAIT; if ((ecx & 0x00000200U) != 0) _features |= CpuFeatures.SSSE3; if ((ecx & 0x00002000U) != 0) _features |= CpuFeatures.CMPXCHG16B; if ((ecx & 0x00080000U) != 0) _features |= CpuFeatures.SSE4_1; if ((ecx & 0x00100000U) != 0) _features |= CpuFeatures.SSE4_2; if ((ecx & 0x00400000U) != 0) _features |= CpuFeatures.MOVBE; if ((ecx & 0x00800000U) != 0) _features |= CpuFeatures.POPCNT; if ((ecx & 0x10000000U) != 0) _features |= CpuFeatures.AVX; if ((edx & 0x00000010U) != 0) _features |= CpuFeatures.RDTSC; if ((edx & 0x00000100U) != 0) _features |= CpuFeatures.CMPXCHG8B; if ((edx & 0x00008000U) != 0) _features |= CpuFeatures.CMOV; if ((edx & 0x00800000U) != 0) _features |= CpuFeatures.MMX; if ((edx & 0x01000000U) != 0) _features |= CpuFeatures.FXSR; if ((edx & 0x02000000U) != 0) _features |= CpuFeatures.SSE | CpuFeatures.MMX_EXT; if ((edx & 0x04000000U) != 0) _features |= CpuFeatures.SSE | CpuFeatures.SSE2; if ((edx & 0x10000000U) != 0) _features |= CpuFeatures.MULTI_THREADING; if (_vendorId == CpuVendor.Amd && (edx & 0x10000000U) != 0) { // AMD sets Multithreading to ON if it has more cores. if (_numberOfProcessors == 1) _numberOfProcessors = 2; } // This comment comes from V8 and I think that its important: // // Opteron Rev E has a bug in which on very rare occasions a locked // instruction doesn't act as a read-acquire barrier if followed by a // non-locked read-modify-write instruction. Rev F has this bug in // pre-release versions, but not in versions released to customers, // so we test only for Rev E, which is family 15, model 32..63 inclusive. if (_vendorId == CpuVendor.Amd && _family == 15 && _model >= 32 && _model <= 63) { _bugs |= CpuBugs.AmdLockMb; } // Calling cpuid with 0x80000000 as the in argument // gets the number of valid extended IDs. eax = 0x80000000; CpuId(ref eax, out ebx, out ecx, out edx); uint exIds = eax; if (exIds > 0x80000004) exIds = 0x80000004; for (a = 0x80000001; a <= exIds; a++) { eax = a; CpuId(ref eax, out ebx, out ecx, out edx); switch (a) { case 0x80000001: if ((ecx & 0x00000001U) != 0) _features |= CpuFeatures.LAHF_SAHF; if ((ecx & 0x00000020U) != 0) _features |= CpuFeatures.LZCNT; if ((ecx & 0x00000040U) != 0) _features |= CpuFeatures.SSE4_A; if ((ecx & 0x00000080U) != 0) _features |= CpuFeatures.MSSE; if ((ecx & 0x00000100U) != 0) _features |= CpuFeatures.PREFETCH; if ((edx & 0x00100000U) != 0) _features |= CpuFeatures.EXECUTE_DISABLE_BIT; if ((edx & 0x00200000U) != 0) _features |= CpuFeatures.FFXSR; if ((edx & 0x00400000U) != 0) _features |= CpuFeatures.MMX_EXT; if ((edx & 0x08000000U) != 0) _features |= CpuFeatures.RDTSCP; if ((edx & 0x20000000U) != 0) _features |= CpuFeatures.X64_BIT; if ((edx & 0x40000000U) != 0) _features |= CpuFeatures.AMD3DNOW_EXT | CpuFeatures.MMX_EXT; if ((edx & 0x80000000U) != 0) _features |= CpuFeatures.AMD3DNOW; break; case 0x80000002: case 0x80000003: case 0x80000004: byte[] brand = new byte[16]; BitConverter.GetBytes(eax).CopyTo(brand, 0); BitConverter.GetBytes(ebx).CopyTo(brand, 4); BitConverter.GetBytes(ecx).CopyTo(brand, 8); BitConverter.GetBytes(edx).CopyTo(brand, 12); _brand = Encoding.ASCII.GetString(brand); break; default: // Additional features can be detected in the future. break; } } } }