示例#1
0
        public CPUID(int thread)
        {
            this.thread = thread;

            uint maxCpuid    = 0;
            uint maxCpuidExt = 0;

            uint eax, ebx, ecx, edx;

            if (thread >= 64)
            {
                throw new ArgumentOutOfRangeException("thread");
            }
            ulong mask = 1UL << thread;

            if (Opcode.CpuidTx(CPUID_0, 0,
                               out eax, out ebx, out ecx, out edx, mask))
            {
                if (eax > 0)
                {
                    maxCpuid = eax;
                }
                else
                {
                    return;
                }

                StringBuilder vendorBuilder = new StringBuilder();
                AppendRegister(vendorBuilder, ebx);
                AppendRegister(vendorBuilder, edx);
                AppendRegister(vendorBuilder, ecx);
                string cpuVendor = vendorBuilder.ToString();
                switch (cpuVendor)
                {
                case "GenuineIntel":
                    vendor = Vendor.Intel;
                    break;

                case "AuthenticAMD":
                    vendor = Vendor.AMD;
                    break;

                default:
                    vendor = Vendor.Unknown;
                    break;
                }
                eax = ebx = ecx = edx = 0;
                if (Opcode.CpuidTx(CPUID_EXT, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    if (eax > CPUID_EXT)
                    {
                        maxCpuidExt = eax - CPUID_EXT;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            else
            {
                return;
            }

            maxCpuid    = Math.Min(maxCpuid, 1024);
            maxCpuidExt = Math.Min(maxCpuidExt, 1024);

            cpuidData = new uint[maxCpuid + 1, 4];
            for (uint i = 0; i < (maxCpuid + 1); i++)
            {
                Opcode.CpuidTx(CPUID_0 + i, 0,
                               out cpuidData[i, 0], out cpuidData[i, 1],
                               out cpuidData[i, 2], out cpuidData[i, 3], mask);
            }

            cpuidExtData = new uint[maxCpuidExt + 1, 4];
            for (uint i = 0; i < (maxCpuidExt + 1); i++)
            {
                Opcode.CpuidTx(CPUID_EXT + i, 0,
                               out cpuidExtData[i, 0], out cpuidExtData[i, 1],
                               out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
            }

            StringBuilder nameBuilder = new StringBuilder();

            for (uint i = 2; i <= 4; i++)
            {
                if (Opcode.CpuidTx(CPUID_EXT + i, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    AppendRegister(nameBuilder, eax);
                    AppendRegister(nameBuilder, ebx);
                    AppendRegister(nameBuilder, ecx);
                    AppendRegister(nameBuilder, edx);
                }
            }
            nameBuilder.Replace('\0', ' ');
            cpuBrandString = nameBuilder.ToString().Trim();
            nameBuilder.Replace("(R)", " ");
            nameBuilder.Replace("(TM)", " ");
            nameBuilder.Replace("(tm)", "");
            nameBuilder.Replace("CPU", "");
            nameBuilder.Replace("Dual-Core Processor", "");
            nameBuilder.Replace("Triple-Core Processor", "");
            nameBuilder.Replace("Quad-Core Processor", "");
            nameBuilder.Replace("Six-Core Processor", "");
            nameBuilder.Replace("Eight-Core Processor", "");
            nameBuilder.Replace("12-Core Processor", "");
            nameBuilder.Replace("16-Core Processor", "");
            nameBuilder.Replace("24-Core Processor", "");
            nameBuilder.Replace("32-Core Processor", "");
            nameBuilder.Replace("64-Core Processor", "");
            nameBuilder.Replace("6-Core Processor", "");
            nameBuilder.Replace("8-Core Processor", "");

            for (int i = 0; i < 10; i++)
            {
                nameBuilder.Replace("  ", " ");
            }
            name = nameBuilder.ToString();
            if (name.Contains("@"))
            {
                name = name.Remove(name.LastIndexOf('@'));
            }
            name = name.Trim();

            this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
                          ((cpuidData[1, 0] & 0x0F00) >> 8);
            this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
                         ((cpuidData[1, 0] & 0xF0) >> 4);
            this.stepping = (cpuidData[1, 0] & 0x0F);

            this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;

            switch (vendor)
            {
            case Vendor.Intel:
                uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
                uint maxCoreIdPerPackage;
                if (maxCpuid >= 4)
                {
                    maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
                }
                else
                {
                    maxCoreIdPerPackage = 1;
                }
                threadMaskWith =
                    NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
                coreMaskWith = NextLog2(maxCoreIdPerPackage);
                break;

            case Vendor.AMD:
                if (this.family == 0x17)
                {
                    coreMaskWith   = (cpuidExtData[8, 2] >> 12) & 0xF;
                    threadMaskWith =
                        NextLog2(((cpuidExtData[0x1E, 1] >> 8) & 0xFF) + 1);
                }
                else
                {
                    uint corePerPackage;
                    if (maxCpuidExt >= 8)
                    {
                        corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
                    }
                    else
                    {
                        corePerPackage = 1;
                    }
                    coreMaskWith   = NextLog2(corePerPackage);
                    threadMaskWith = 0;
                }
                break;

            default:
                threadMaskWith = 0;
                coreMaskWith   = 0;
                break;
            }

            processorId = (apicId >> (int)(coreMaskWith + threadMaskWith));
            coreId      = ((apicId >> (int)(threadMaskWith))
                           - (processorId << (int)(coreMaskWith)));
            threadId = apicId
                       - (processorId << (int)(coreMaskWith + threadMaskWith))
                       - (coreId << (int)(threadMaskWith));
        }
示例#2
0
文件: CPUID.cs 项目: EntityFX/CPU-E
        private void PrepareIntelCaches(ref uint eax, ref uint ebx, ref uint ecx, ref uint edx, ulong mask)
        {
            uint cacheType = 0xFFFF;
            uint leaf      = 0;

            while (cacheType != 0)
            {
                if (Opcode.CpuidTx(CPUID_4, leaf,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    cacheType = eax & 0x1f;
                }
                else
                {
                    cacheType = 0;
                }

                if (cacheType == 0)
                {
                    continue;
                }

                var level = (eax >> 5) & 0x07;
                var waysOfAssociativity = ((ebx >> 22) & 0x3FF) + 1;
                var linePartitions      = ((ebx >> 12) & 0x3FF) + 1;
                var lineSize            = (ushort)((ebx & 0xFFF) + 1);
                var sets = ecx + 1;
                var size = (waysOfAssociativity * linePartitions * lineSize * sets) / 1024;

                var fullAssociative = Convert.ToBoolean((eax >> 9) & 1);

                CacheAssociativity cacheAssociativity = CacheAssociativity.Disabled;

                if (fullAssociative)
                {
                    cacheAssociativity = CacheAssociativity.Fully;
                }
                else if (waysOfAssociativity > 0)
                {
                    cacheAssociativity = (CacheAssociativity)waysOfAssociativity;
                }

                var cacheItem = new CacheItem()
                {
                    Level         = (CacheLevels)level,
                    LineSize      = lineSize,
                    SizeKbytes    = size,
                    CacheType     = (CacheType)cacheType,
                    Associativity = cacheAssociativity
                };

                if (caches.ContainsKey(cacheItem.Level))
                {
                    var cachesOfLevel = caches[cacheItem.Level].ToList();
                    cachesOfLevel.Add(cacheItem);
                    caches[cacheItem.Level] = cachesOfLevel.ToArray();
                }
                else
                {
                    caches[cacheItem.Level] = new CacheItem[] { cacheItem };
                }

                leaf++;
            }
        }
示例#3
0
文件: CPUID.cs 项目: EntityFX/CPU-E
        public CPUID(int thread)
        {
            this.thread = thread;

            uint maxCpuid      = 0;
            uint maxCpuidExt   = 0;
            uint maxCpuidCache = 0;

            uint eax, ebx, ecx, edx;

            if (thread >= 64)
            {
                throw new ArgumentOutOfRangeException("thread");
            }
            ulong mask = 1UL << thread;

            if (Opcode.CpuidTx(CPUID_0, 0,
                               out eax, out ebx, out ecx, out edx, mask))
            {
                if (eax > 0)
                {
                    maxCpuid = eax;
                }
                else
                {
                    return;
                }

                StringBuilder vendorBuilder = new StringBuilder();
                AppendRegister(vendorBuilder, ebx);
                AppendRegister(vendorBuilder, edx);
                AppendRegister(vendorBuilder, ecx);
                string cpuVendor = vendorBuilder.ToString();
                switch (cpuVendor)
                {
                case "GenuineIntel":
                    vendor = Vendor.Intel;
                    break;

                case "AuthenticAMD":
                    vendor = Vendor.AMD;
                    break;

                default:
                    vendor = Vendor.Unknown;
                    break;
                }
                eax = ebx = ecx = edx = 0;
                if (Opcode.CpuidTx(CPUID_EXT, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    if (eax > CPUID_EXT)
                    {
                        maxCpuidExt = eax - CPUID_EXT;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    throw new ArgumentOutOfRangeException("thread");
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("thread");
            }

            maxCpuid      = Math.Min(maxCpuid, 1024);
            maxCpuidExt   = Math.Min(maxCpuidExt, 1024);
            maxCpuidCache = Math.Min(maxCpuidCache, 1024);

            cpuidData = new uint[maxCpuid + 1, 4];
            for (uint i = 0; i < (maxCpuid + 1); i++)
            {
                Opcode.CpuidTx(CPUID_0 + i, 0,
                               out cpuidData[i, 0], out cpuidData[i, 1],
                               out cpuidData[i, 2], out cpuidData[i, 3], mask);
            }

            cpuidExtData = new uint[maxCpuidExt + 1, 4];
            for (uint i = 0; i < (maxCpuidExt + 1); i++)
            {
                Opcode.CpuidTx(CPUID_EXT + i, 0,
                               out cpuidExtData[i, 0], out cpuidExtData[i, 1],
                               out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
            }

            StringBuilder nameBuilder = new StringBuilder();

            for (uint i = 2; i <= 4; i++)
            {
                if (Opcode.CpuidTx(CPUID_EXT + i, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    AppendRegister(nameBuilder, eax);
                    AppendRegister(nameBuilder, ebx);
                    AppendRegister(nameBuilder, ecx);
                    AppendRegister(nameBuilder, edx);
                }
            }
            nameBuilder.Replace('\0', ' ');
            cpuBrandString = nameBuilder.ToString().Trim();
            nameBuilder.Replace("(R)", " ");
            nameBuilder.Replace("(TM)", " ");
            nameBuilder.Replace("(tm)", "");
            nameBuilder.Replace("CPU", "");
            nameBuilder.Replace("Quad-Core Processor", "");
            nameBuilder.Replace("Six-Core Processor", "");
            nameBuilder.Replace("Eight-Core Processor", "");
            nameBuilder.Replace("APU with Radeon HD Graphics", "");
            for (int i = 0; i < 10; i++)
            {
                nameBuilder.Replace("  ", " ");
            }
            name = nameBuilder.ToString();
            if (name.Contains("@"))
            {
                name = name.Remove(name.LastIndexOf('@'));
            }
            name = name.Trim();

            this.familyId = ((cpuidData[1, 0] & 0x0F00) >> 8);
            this.family   = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
                            ((cpuidData[1, 0] & 0x0F00) >> 8);
            this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
                         ((cpuidData[1, 0] & 0xF0) >> 4);
            this.stepping = (cpuidData[1, 0] & 0x0F);

            this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;

            switch (vendor)
            {
            case Vendor.Intel:
                uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
                uint maxCoreIdPerPackage;
                if (maxCpuid >= 4)
                {
                    maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
                }
                else
                {
                    maxCoreIdPerPackage = 1;
                }
                threadMaskWith =
                    NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
                coreMaskWith = NextLog2(maxCoreIdPerPackage);
                break;

            case Vendor.AMD:
                uint corePerPackage;
                if (maxCpuidExt >= 8)
                {
                    corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
                }
                else
                {
                    corePerPackage = 1;
                }
                threadMaskWith = 0;
                coreMaskWith   = NextLog2(corePerPackage);
                break;

            default:
                threadMaskWith = 0;
                coreMaskWith   = 0;
                break;
            }

            if (Opcode.CpuidTx(CPUID_1, 0,
                               out eax, out ebx, out ecx, out edx, mask))
            {
                instructionsExtensions.MMX  = Convert.ToBoolean((edx >> 23) & 1);
                instructionsExtensions.SSE  = Convert.ToBoolean((edx >> 25) & 1);
                instructionsExtensions.SSE2 = Convert.ToBoolean((edx >> 25) & 1);

                instructionsExtensions.SSE3   = Convert.ToBoolean((ecx) & 1);
                instructionsExtensions.SSSE3  = Convert.ToBoolean((ecx >> 9) & 1);
                instructionsExtensions.SSE4_1 = Convert.ToBoolean((ecx >> 19) & 1);
                instructionsExtensions.SSE4_2 = Convert.ToBoolean((ecx >> 20) & 1);

                instructionsExtensions.AVX  = Convert.ToBoolean((ecx >> 28) & 1);
                instructionsExtensions.FMA3 = Convert.ToBoolean((ecx >> 12) & 1);
                instructionsExtensions.AES  = Convert.ToBoolean((ecx >> 25) & 1);
            }

            if (Opcode.CpuidTx(CPUID_7, 0,
                               out eax, out ebx, out ecx, out edx, mask))
            {
                instructionsExtensions.AVX2    = Convert.ToBoolean((ebx >> 5) & 1);
                instructionsExtensions.AVX512F = Convert.ToBoolean((ebx >> 16) & 1);
                instructionsExtensions.TSX     = Convert.ToBoolean((ebx >> 11) & 1);
            }

            if (Vendor == Vendor.AMD)
            {
                instructionsExtensions._3DNow    = Convert.ToBoolean((cpuidExtData[1, 3] >> 31) & 1);
                instructionsExtensions._3DNowExt = Convert.ToBoolean((cpuidExtData[1, 3] >> 30) & 1);
                instructionsExtensions.MMXExt    = Convert.ToBoolean((cpuidExtData[1, 3] >> 22) & 1);


                instructionsExtensions.SSE4a = Convert.ToBoolean((cpuidExtData[1, 2] >> 6) & 1);
                instructionsExtensions.FMA4  = Convert.ToBoolean((cpuidExtData[1, 2] >> 16) & 1);

                PrepareAmdCaches(cpuidExtData);
            }


            if (Vendor == Vendor.Intel)
            {
                PrepareIntelCaches(ref eax, ref ebx, ref ecx, ref edx, mask);
            }

            if (!caches.ContainsKey(CacheLevels.Level2))
            {
                var l2Cache = new CacheItem()
                {
                    Level      = CacheLevels.Level2,
                    LineSize   = (byte)(cpuidExtData[6, 2] & 0xFF),
                    SizeKbytes = (ushort)(cpuidExtData[6, 2] >> 16 & 0xFFFF)
                };

                var l2Way = (byte)(cpuidExtData[6, 2] >> 12 & 0xFF);

                l2Cache.Associativity = GetAssociativity(l2Way);

                caches.Add(CacheLevels.Level2, new CacheItem[] { l2Cache });
            }


            is64bit = Convert.ToBoolean((cpuidExtData[1, 3] >> 29 & 0x1));

            processorId = (apicId >> (int)(coreMaskWith + threadMaskWith));
            coreId      = ((apicId >> (int)(threadMaskWith))
                           - (processorId << (int)(coreMaskWith)));
            threadId = apicId
                       - (processorId << (int)(coreMaskWith + threadMaskWith))
                       - (coreId << (int)(threadMaskWith));
        }
示例#4
0
    public CPUID(int thread) {
      this.thread = thread;

      uint maxCpuid = 0;
      uint maxCpuidExt = 0;

      uint eax, ebx, ecx, edx;

      if (thread >= 64)
        throw new ArgumentOutOfRangeException("thread");
      ulong mask = 1UL << thread;

      if (Opcode.CpuidTx(CPUID_0, 0,
          out eax, out ebx, out ecx, out edx, mask)) {
        if (eax > 0)
          maxCpuid = eax;
        else
          return;

        StringBuilder vendorBuilder = new StringBuilder();
        AppendRegister(vendorBuilder, ebx);
        AppendRegister(vendorBuilder, edx);
        AppendRegister(vendorBuilder, ecx);
        string cpuVendor = vendorBuilder.ToString();
        switch (cpuVendor) {
          case "GenuineIntel":
            vendor = Vendor.Intel;
            break;
          case "AuthenticAMD":
            vendor = Vendor.AMD;
            break;
          default:
            vendor = Vendor.Unknown;
            break;
        }
        eax = ebx = ecx = edx = 0;
        if (Opcode.CpuidTx(CPUID_EXT, 0,
          out eax, out ebx, out ecx, out edx, mask)) {
          if (eax > CPUID_EXT)
            maxCpuidExt = eax - CPUID_EXT;
          else
            return;
        } else {
          throw new ArgumentOutOfRangeException("thread");
        }
      } else {
        throw new ArgumentOutOfRangeException("thread");
      }

      maxCpuid = Math.Min(maxCpuid, 1024);
      maxCpuidExt = Math.Min(maxCpuidExt, 1024);   

      cpuidData = new uint[maxCpuid + 1, 4];
      for (uint i = 0; i < (maxCpuid + 1); i++)
        Opcode.CpuidTx(CPUID_0 + i, 0, 
          out cpuidData[i, 0], out cpuidData[i, 1],
          out cpuidData[i, 2], out cpuidData[i, 3], mask);

      cpuidExtData = new uint[maxCpuidExt + 1, 4];
      for (uint i = 0; i < (maxCpuidExt + 1); i++)
        Opcode.CpuidTx(CPUID_EXT + i, 0, 
          out cpuidExtData[i, 0], out cpuidExtData[i, 1], 
          out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);

      StringBuilder nameBuilder = new StringBuilder();
      for (uint i = 2; i <= 4; i++) {
        if (Opcode.CpuidTx(CPUID_EXT + i, 0, 
          out eax, out ebx, out ecx, out edx, mask)) 
        {
          AppendRegister(nameBuilder, eax);
          AppendRegister(nameBuilder, ebx);
          AppendRegister(nameBuilder, ecx);
          AppendRegister(nameBuilder, edx);
        }
      }
      nameBuilder.Replace('\0', ' ');
      cpuBrandString = nameBuilder.ToString().Trim();
      nameBuilder.Replace("(R)", " ");
      nameBuilder.Replace("(TM)", " ");
      nameBuilder.Replace("(tm)", "");
      nameBuilder.Replace("CPU", "");
      nameBuilder.Replace("Quad-Core Processor", "");
      nameBuilder.Replace("Six-Core Processor", "");
      nameBuilder.Replace("Eight-Core Processor", "");
      for (int i = 0; i < 10; i++) nameBuilder.Replace("  ", " ");
      name = nameBuilder.ToString();
      if (name.Contains("@"))
        name = name.Remove(name.LastIndexOf('@'));
      name = name.Trim();      

      this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
        ((cpuidData[1, 0] & 0x0F00) >> 8);
      this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
        ((cpuidData[1, 0] & 0xF0) >> 4);
      this.stepping = (cpuidData[1, 0] & 0x0F);

      this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;

      switch (vendor) {
        case Vendor.Intel:
          uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
          uint maxCoreIdPerPackage;
          if (maxCpuid >= 4)
            maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
          else
            maxCoreIdPerPackage = 1;
          threadMaskWith = 
            NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
          coreMaskWith = NextLog2(maxCoreIdPerPackage);
          break;
        case Vendor.AMD:
          uint corePerPackage;
          if (maxCpuidExt >= 8)
            corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
          else
            corePerPackage = 1;
          threadMaskWith = 0;
          coreMaskWith = NextLog2(corePerPackage);
          
          if (this.family == 0x17)
          {
            // ApicIdCoreIdSize: APIC ID size. 
            // cores per DIE 
            // we need this for Ryzen 5 (4 cores, 8 threads) ans Ryzen 6 (6 cores, 12 threads) 
            // Ryzen 5: [core0][core1][dummy][dummy][core2][core3] (Core0 EBX = 00080800, Core2 EBX = 08080800) 
            uint max_cores_per_die = (cpuidExtData[8, 2] >> 12) & 0xF;
            switch (max_cores_per_die)
            {
              case 0x04: // Ryzen 
                coreMaskWith = NextLog2(16);
                break;
              case 0x05:// Threadripper 
                coreMaskWith = NextLog2(32);
                break;
              case 0x06:// Epic 
                coreMaskWith = NextLog2(64);
                break;
            }
          }
          break;
        default:
          threadMaskWith = 0;
          coreMaskWith = 0;
          break;
      }

      processorId = (apicId >> (int)(coreMaskWith + threadMaskWith));
      coreId = ((apicId >> (int)(threadMaskWith)) 
        - (processorId << (int)(coreMaskWith)));
      threadId = apicId
        - (processorId << (int)(coreMaskWith + threadMaskWith))
        - (coreId << (int)(threadMaskWith)); 
    }
示例#5
0
        public CpuId(int thread)
        {
            Thread = thread;

            uint maxCpuid;
            uint maxCpuidExt;

            if (thread >= 64)
            {
                throw new ArgumentOutOfRangeException(nameof(thread));
            }
            var mask = 1UL << thread;

            if (Opcode.CpuidTx(CPUID_0, 0, out var eax, out var ebx, out var ecx, out var edx, mask))
            {
                if (eax > 0)
                {
                    maxCpuid = eax;
                }
                else
                {
                    return;
                }

                var vendorBuilder = new StringBuilder();
                AppendRegister(vendorBuilder, ebx);
                AppendRegister(vendorBuilder, edx);
                AppendRegister(vendorBuilder, ecx);
                var cpuVendor = vendorBuilder.ToString();
                switch (cpuVendor)
                {
                case "GenuineIntel":
                    Vendor = Vendor.Intel;
                    break;

                case "AuthenticAMD":
                    Vendor = Vendor.AMD;
                    break;

                default:
                    Vendor = Vendor.Unknown;
                    break;
                }

                if (Opcode.CpuidTx(CPUID_EXT, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    if (eax > CPUID_EXT)
                    {
                        maxCpuidExt = eax - CPUID_EXT;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(thread));
                }
            }
示例#6
0
        public CPUID(int thread)
        {
            Thread = thread;

            uint maxCpuid    = 0;
            uint maxCpuidExt = 0;

            uint eax, ebx, ecx, edx;

            if (thread >= 64)
            {
                throw new ArgumentOutOfRangeException("thread");
            }
            var mask = 1UL << thread;

            if (Opcode.CpuidTx(CPUID_0, 0,
                               out eax, out ebx, out ecx, out edx, mask))
            {
                if (eax > 0)
                {
                    maxCpuid = eax;
                }
                else
                {
                    return;
                }

                var vendorBuilder = new StringBuilder();
                AppendRegister(vendorBuilder, ebx);
                AppendRegister(vendorBuilder, edx);
                AppendRegister(vendorBuilder, ecx);
                var cpuVendor = vendorBuilder.ToString();
                switch (cpuVendor)
                {
                case "GenuineIntel":
                    Vendor = Vendor.Intel;
                    break;

                case "AuthenticAMD":
                    Vendor = Vendor.AMD;
                    break;

                default:
                    Vendor = Vendor.Unknown;
                    break;
                }
                eax = ebx = ecx = edx = 0;
                if (Opcode.CpuidTx(CPUID_EXT, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    if (eax > CPUID_EXT)
                    {
                        maxCpuidExt = eax - CPUID_EXT;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    throw new ArgumentOutOfRangeException("thread");
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("thread");
            }

            maxCpuid    = Math.Min(maxCpuid, 1024);
            maxCpuidExt = Math.Min(maxCpuidExt, 1024);

            Data = new uint[maxCpuid + 1, 4];
            for (uint i = 0; i < (maxCpuid + 1); i++)
            {
                Opcode.CpuidTx(CPUID_0 + i, 0,
                               out Data[i, 0], out Data[i, 1],
                               out Data[i, 2], out Data[i, 3], mask);
            }

            ExtData = new uint[maxCpuidExt + 1, 4];
            for (uint i = 0; i < (maxCpuidExt + 1); i++)
            {
                Opcode.CpuidTx(CPUID_EXT + i, 0,
                               out ExtData[i, 0], out ExtData[i, 1],
                               out ExtData[i, 2], out ExtData[i, 3], mask);
            }

            var nameBuilder = new StringBuilder();

            for (uint i = 2; i <= 4; i++)
            {
                if (Opcode.CpuidTx(CPUID_EXT + i, 0,
                                   out eax, out ebx, out ecx, out edx, mask))
                {
                    AppendRegister(nameBuilder, eax);
                    AppendRegister(nameBuilder, ebx);
                    AppendRegister(nameBuilder, ecx);
                    AppendRegister(nameBuilder, edx);
                }
            }
            nameBuilder.Replace('\0', ' ');
            BrandString = nameBuilder.ToString().Trim();
            nameBuilder.Replace("(R)", " ");
            nameBuilder.Replace("(TM)", " ");
            nameBuilder.Replace("(tm)", "");
            nameBuilder.Replace("CPU", "");
            nameBuilder.Replace("Quad-Core Processor", "");
            nameBuilder.Replace("Six-Core Processor", "");
            nameBuilder.Replace("Eight-Core Processor", "");
            for (var i = 0; i < 10; i++)
            {
                nameBuilder.Replace("  ", " ");
            }
            Name = nameBuilder.ToString();
            if (Name.Contains("@"))
            {
                Name = Name.Remove(Name.LastIndexOf('@'));
            }
            Name = Name.Trim();

            Family = ((Data[1, 0] & 0x0FF00000) >> 20) +
                     ((Data[1, 0] & 0x0F00) >> 8);
            Model = ((Data[1, 0] & 0x0F0000) >> 12) +
                    ((Data[1, 0] & 0xF0) >> 4);
            Stepping = (Data[1, 0] & 0x0F);

            ApicId = (Data[1, 1] >> 24) & 0xFF;

            switch (Vendor)
            {
            case Vendor.Intel:
                var  maxCoreAndThreadIdPerPackage = (Data[1, 1] >> 16) & 0xFF;
                uint maxCoreIdPerPackage;
                if (maxCpuid >= 4)
                {
                    maxCoreIdPerPackage = ((Data[4, 0] >> 26) & 0x3F) + 1;
                }
                else
                {
                    maxCoreIdPerPackage = 1;
                }
                threadMaskWith =
                    NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
                coreMaskWith = NextLog2(maxCoreIdPerPackage);
                break;

            case Vendor.AMD:
                uint corePerPackage;
                if (maxCpuidExt >= 8)
                {
                    corePerPackage = (ExtData[8, 2] & 0xFF) + 1;
                }
                else
                {
                    corePerPackage = 1;
                }
                threadMaskWith = 0;
                coreMaskWith   = NextLog2(corePerPackage);
                break;

            default:
                threadMaskWith = 0;
                coreMaskWith   = 0;
                break;
            }

            ProcessorId = (ApicId >> (int)(coreMaskWith + threadMaskWith));
            CoreId      = ((ApicId >> (int)(threadMaskWith))
                           - (ProcessorId << (int)(coreMaskWith)));
            ThreadId = ApicId
                       - (ProcessorId << (int)(coreMaskWith + threadMaskWith))
                       - (CoreId << (int)(threadMaskWith));
        }