⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpuinfo.cpp

📁 一个用vc获取系统硬件信息的例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   DWORD dwEcx = 0;
   DWORD dwEdx = 0;

   __asm
   {
      mov      eax, 2
      CPUID
      cmp      al, 1
      jne      end_find_intel_cacheinfo

      // if one iteration isn't enough, this code won't produce anything meaningful!
      // this is from intel; look into changing it
      mov      dwEax, eax
      mov      dwEbx, ebx
      mov      dwEcx, ecx
      mov      dwEdx, edx

end_find_intel_cacheinfo:

   }

   m_cpuStats.setCacheEax(dwEax);
   m_cpuStats.setCacheEbx(dwEbx);
   m_cpuStats.setCacheEcx(dwEcx);
   m_cpuStats.setCacheEdx(dwEdx);
   if (m_fDebug) m_osDebugResults << "Intel Cache Info EAX: " << dwEax << endl;
   if (m_fDebug) m_osDebugResults << "Intel Cache Info EBX: " << dwEbx << endl;
   if (m_fDebug) m_osDebugResults << "Intel Cache Info ECX: " << dwEcx << endl;
   if (m_fDebug) m_osDebugResults << "Intel Cache Info EDX: " << dwEdx << endl;
}


// this function is mostly ripped from intel's developer.intel.com webpage
// on the CPUID instruction
void CpuInfo::determineOldIntelName()
{
   bool fIsCeleron;
   bool fIsXeon;

   struct brand_entry
   {
      long  lBrandValue;
      char* pszBrand;
   };

   struct brand_entry brand_table[BRANDTABLESIZE] = 
   {
      1, "Genuine Intel Celeron(TM) processor",
      2, "Genuine Intel Pentium(R) III processor",
      3, "Genuine Intel Pentium(R) III Xeon(TM) processor",
      8, "Genuine Intel Pentium(R) 4 processor"
   };

   /* we don't support old intel cpu's that don't know CPUID
   if (m_cpuStats.getKnowsCpuId() == 0)
   {
   // 8086 - 80486
   switch(m_cpuStats.getFamily())
   {
   case 3:
      m_strCpuIdentification = "Intel386(TM) processor";
      break;
   case 4:
      m_strCpuIdentification = "Intel486(TM) processor";
      break;
   default:
      m_strCpuIdentification = "Unknown processor";
      break;
   } */

   if (determineHighestCpuId() < NAMESTRING_FEATURE)
   {
      switch (m_cpuStats.getFamily())
      {
      case 4:  // 486
         switch(m_cpuStats.getModel())
         {
         case 0:
         case 1:
            m_cpuStats.setName("Intel486(TM) DX processor");
            break;
         case 2:
            m_cpuStats.setName("Intel486(TM) SX processor");
            break;
         case 3:
            m_cpuStats.setName("IntelDX2(TM) processor");
            break;
         case 4:
            m_cpuStats.setName("Intel486(TM) processor");
            break;
         case 5:
            m_cpuStats.setName("IntelSX2(TM) processor");
            break;
         case 7:
            m_cpuStats.setName("Writeback Enhanced IntelDX2(TM) processor");
            break;
         case 8:
            m_cpuStats.setName("IntelDX4(TM) processor");
            break;
         default:
            m_cpuStats.setName("Intel 486 processor");
            break;
			}

			break;

      case 5:  // pentium
         m_cpuStats.setName("Intel Pentium(R) processor");
         break;

      case 6:  // pentium II and family
         switch (m_cpuStats.getModel())
         {
         case 1:
            m_cpuStats.setName("Intel Pentium(R) Pro processor");
            break;
         case 3:
            m_cpuStats.setName("Intel Pentium(R) II processor, model 3");
            break;
         case 5:
         case 7:
            fIsCeleron = false;
            fIsXeon = false;

            determineCeleronAndXeon(m_cpuStats.getCacheEax(), &fIsCeleron, &fIsXeon, true);
            determineCeleronAndXeon(m_cpuStats.getCacheEbx(), &fIsCeleron, &fIsXeon);
            determineCeleronAndXeon(m_cpuStats.getCacheEcx(), &fIsCeleron, &fIsXeon);
            determineCeleronAndXeon(m_cpuStats.getCacheEdx(), &fIsCeleron, &fIsXeon);
        
            if (fIsCeleron)
            {
               m_cpuStats.setName("Intel Celeron(TM) processor, model 5");
            }
            else
            {
               if (fIsXeon)
               {
                  if (m_cpuStats.getModel() == 5)
                  {
                     m_cpuStats.setName("Intel Pentium(R) II Xeon(TM) processor");
                  }
                  else
                  {
                     m_cpuStats.setName("Intel Pentium(R) III Xeon(TM) processor");
                  }
               }
               else
               {
                  if (m_cpuStats.getModel() == 5)
                  {
                     m_cpuStats.setName("Intel Pentium(R) II processor, model 5");
                  }
                  else
                  {
                     m_cpuStats.setName("Intel Pentium(R) III processor");
                  }
               }
            }

            break;

         case 6:
            m_cpuStats.setName("Intel Celeron(TM) processor, model 6");
            break;
         case 8:
            m_cpuStats.setName("Intel Pentium(R) III Coppermine processor");
            break;
         default:
            {
               int brand_index = 0;
               while ((brand_index < BRANDTABLESIZE) &&
                      ((m_cpuStats.getFeatureEbx() & 0xff) != brand_table[brand_index].lBrandValue))
               {
                  brand_index++;
               }

               if (brand_index < BRANDTABLESIZE)
               {
                  m_cpuStats.setName(brand_table[brand_index].pszBrand);
               }
               else
               {
                  m_cpuStats.setName("Unknown Genuine Intel processor");
               }

               break;
            }
         } 
      }

      if (m_cpuStats.getFeature(MMX_FLAG))
      {
         string strName = m_cpuStats.getName();
         strName += " with MMX";
         m_cpuStats.setName(strName);
      }		   
   }

   if (m_fDebug) m_osDebugResults << "CPU Old Intel name: " << m_cpuStats.getName() << endl;
}

// this is ripped from intel, but put into function form. instead of testing for
// each register, we have a function to test a register's value.
// newer processors won't even use this.
void CpuInfo::determineCeleronAndXeon(DWORD dwRegisterCache, bool* pfIsCeleron, bool* pfIsXeon, bool fIsEax)
{
   DWORD dwCacheTemp;

   dwCacheTemp = dwRegisterCache & 0xFF000000;
   if (dwCacheTemp == 0x40000000)
   {
      *pfIsCeleron = true;
   }
   if ((dwCacheTemp >= 0x44000000) && (dwCacheTemp <= 0x45000000))
   {
      *pfIsXeon = true;
   }

   dwCacheTemp = dwRegisterCache & 0xFF0000;
   if (dwCacheTemp == 0x400000)
   {
      *pfIsCeleron = true;
   }
   if ((dwCacheTemp >= 0x440000) && (dwCacheTemp <= 0x450000))
   {
      *pfIsXeon = true;
   }

   dwCacheTemp = dwRegisterCache & 0xFF00;
   if (dwCacheTemp == 0x4000)
   {
      *pfIsCeleron = true;
   }
   if ((dwCacheTemp >= 0x4400) && (dwCacheTemp <= 0x4500))
   {
      *pfIsXeon = true;
   }

   if (!fIsEax)
   {
      dwCacheTemp = dwRegisterCache & 0xFF;     // possibly not needed for m_dwCacheEax
      if (dwCacheTemp == 0x40000000)            
      {
         *pfIsCeleron = true;
      }
      if ((dwCacheTemp >= 0x44000000) && (dwCacheTemp <= 0x45000000))
      {
         *pfIsXeon = true;
      }
   }
}

//------------------------------------------------------------
// This speed-determination algorithm was taken from 
// Alexandre Cesari -- acesari@aclogic.com
//
DWORD CpuInfo::calculateCpuSpeed(void) const
{
   DWORD dwStartTicks = 0;
   DWORD dwEndTicks = 0;
   DWORD dwTotalTicks = 0;
   DWORD dwCpuSpeed = 0;
   __int64 n64Frequency ;
   __int64 n64Start;
   __int64 n64Stop ;

   if (QueryPerformanceFrequency((LARGE_INTEGER*)&n64Frequency)) 
   {
      QueryPerformanceCounter((LARGE_INTEGER*)&n64Start);
      dwStartTicks = determineTimeStamp();

      Sleep(300);

      dwEndTicks = determineTimeStamp();

      QueryPerformanceCounter((LARGE_INTEGER*)&n64Stop);
      dwTotalTicks = dwEndTicks - dwStartTicks;
      dwCpuSpeed = dwTotalTicks / ((1000000*(n64Stop-n64Start))/n64Frequency);
   } 
   else
   {
      dwCpuSpeed = 0;
   }
   
   return (dwCpuSpeed);
}

// this function is ripped from amd
DWORD CpuInfo::calculateCpuSpeedMethod2(void) const
{
   int   nTimeStart = 0;
   int   nTimeStop = 0;
   DWORD dwStartTicks = 0;
   DWORD dwEndTicks = 0;
   DWORD dwTotalTicks = 0;
   DWORD dwCpuSpeed = 0;

   nTimeStart = timeGetTime();

   for(;;)
   {
      nTimeStop = timeGetTime();

      if ((nTimeStop - nTimeStart) > 1)
      {
         dwStartTicks = determineTimeStamp();
         break;
      }
   }

   nTimeStart = nTimeStop;

   for(;;)
   {
      nTimeStop = timeGetTime();
      if ((nTimeStop - nTimeStart) > 500)    // one-half second
      {
         dwEndTicks = determineTimeStamp();
         break;
      }
   }

   dwTotalTicks = dwEndTicks - dwStartTicks;
   dwCpuSpeed = dwTotalTicks / 500000;

   return (dwCpuSpeed);
}

// Not always accurate but order of magnitude faster
//
//   Copyright (c) 2001 J. Michael McGarrah (mcgarrah@mcgarware.com)
//
DWORD CpuInfo::getCpuSpeedFromRegistry(void) const
{
   HKEY hKey;
   LONG result;
   DWORD dwSpeed = 0;
   DWORD dwType = 0;
   DWORD dwSpeedSize;

   // Get the processor speed from registry
   result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                           "Hardware\\Description\\System\\CentralProcessor\\0",
                           0,
                           KEY_QUERY_VALUE,
                           &hKey);

   // Check if the function has succeeded.
   if (result == ERROR_SUCCESS)
   {
      result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, (LPBYTE)&dwSpeed, &dwSpeedSize);

      if (result == ERROR_SUCCESS) {
         //----------------------------------------------------------
         // this function was modified so that it doesn't actually
         // modify the object in any way. it's more of a utility
         // function like calculateCpuSpeed() and 
         // calculateCpuSpeedMethod2()
         //
      }
      else
      {
         // explicity make the speed 0 just in case RegQueryValueEx puts a value in dwSpeed
         dwSpeed = 0;
      }
   }
   else
   {
   }

   // Make sure to close the reg key
   RegCloseKey (hKey);

   return (dwSpeed);
}

// stolen from amd
DWORD CpuInfo::determineTimeStamp(void) const
{
   DWORD dwTickVal;

   __asm
   {
      _emit 0Fh
      _emit 31h
      mov   dwTickVal, eax
   }

   return (dwTickVal);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -