C++ 如何确定机器上的硬件(CPU 和 RAM)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/850774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to determine the hardware (CPU and RAM) on a machine?
提问by Robert Gould
I'm working on a cross platform profiling suite, and would like to add information about the machine's CPU (architecture/clock speed/cores) and RAM(total) to the report of each run. Currently I need to target Windows and Unix, so I need methods to obtain this information from both platforms, any clues?
我正在开发一个跨平台的分析套件,并想在每次运行的报告中添加有关机器 CPU(架构/时钟速度/内核)和 RAM(总计)的信息。目前我需要针对 Windows 和 Unix,所以我需要从两个平台获取这些信息的方法,有什么线索吗?
Edit:Thanks for the great answers, Now I got CPU architecture, CPU number of cores and total Memory, but I'm still lacking a clockspeed for the CPU any ideas for that one?
编辑:感谢您提供出色的答案,现在我获得了 CPU 架构、CPU 内核数和总内存,但我仍然缺乏 CPU 的时钟速度,对此有什么想法吗?
回答by i_am_jorf
On Windows you can use GlobalMemoryStatusExto get the amount of actual RAM.
在 Windows 上,您可以使用GlobalMemoryStatusEx来获取实际 RAM 的数量。
Processor information can be obtained via GetSystemInfo.
处理器信息可以通过GetSystemInfo获得。
回答by bsruth
Here is one method for getting the information you want on a Windows machine. I copied and pasted it from an actual project with some minor modifications, so feel free to clean it up to make more sense.
这是在 Windows 计算机上获取所需信息的一种方法。我从一个实际项目中复制并粘贴了一些小的修改,所以请随意清理它以使其更有意义。
int CPUInfo[4] = {-1};
unsigned nExIds, i = 0;
char CPUBrandString[0x40];
// Get the information associated with each extended ID.
__cpuid(CPUInfo, 0x80000000);
nExIds = CPUInfo[0];
for (i=0x80000000; i<=nExIds; ++i)
{
__cpuid(CPUInfo, i);
// Interpret CPU brand string
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
}
//string includes manufacturer, model and clockspeed
cout << "CPU Type: " << CPUBrandString << endl;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
cout << "Number of Cores: " << sysInfo.dwNumberOfProcessors << endl;
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx(&statex);
cout << "Total System Memory: " << (statex.ullTotalPhys/1024)/1024 << "MB" << endl;
For more information, see GetSystemInfo, GlobalMemoryStatusExand __cpuid. Although I didn't include it, you can also determine if the OS is 32 or 64 bit via the GetSystemInfo function.
有关更多信息,请参阅GetSystemInfo、GlobalMemoryStatusEx和__cpuid。虽然我没有包括它,但您也可以通过 GetSystemInfo 函数确定操作系统是 32 位还是 64 位。
回答by Robert Gould
On Windows to determine CPU clock speed:
在 Windows 上确定 CPU 时钟速度:
double CPUSpeed()
{
wchar_t Buffer[_MAX_PATH];
DWORD BufSize = _MAX_PATH;
DWORD dwMHz = _MAX_PATH;
HKEY hKey;
// open the key where the proc speed is hidden:
long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"HARDWARE\DESCRIPTION\System\CentralProcessor\0",
0,
KEY_READ,
&hKey);
if(lError != ERROR_SUCCESS)
{// if the key is not found, tell the user why:
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lError,
0,
Buffer,
_MAX_PATH,
0);
wprintf(Buffer);
return 0;
}
// query the key:
RegQueryValueEx(hKey, L"~MHz", NULL, NULL, (LPBYTE) &dwMHz, &BufSize);
return (double)dwMHz;
}
回答by Chris Jester-Young
The CPU is easy. Use the cpuid
instruction. I'll leave other posters to find a portable way to determine how much RAM a system has. :-)
CPU很简单。使用cpuid
说明。我将留下其他海报以找到一种便携式方法来确定系统具有多少 RAM。:-)
For Linux-specific methods, you can access /proc/meminfo
(and /proc/cpuinfo
, if you can't be bothered to parse cpuid
responses).
对于 Linux 特定的方法,您可以访问/proc/meminfo
(并且/proc/cpuinfo
,如果您不想解析cpuid
响应)。
回答by Mate Zabo
For Linux with GCC you can use a very similar solution like windows. You need to include the <cpuid.h>
and you need to modify the input for the __cpuid()
method based on this.
对于带有 GCC 的 Linux,您可以使用非常相似的解决方案,例如 windows。您需要包含<cpuid.h>
并且您需要__cpuid()
基于此修改方法的输入。
#include <cpuid.h>
char CPUBrandString[0x40];
unsigned int CPUInfo[4] = {0,0,0,0};
__cpuid(0x80000000, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
unsigned int nExIds = CPUInfo[0];
memset(CPUBrandString, 0, sizeof(CPUBrandString));
for (unsigned int i = 0x80000000; i <= nExIds; ++i)
{
__cpuid(i, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
}
cout << "CPU Type: " << CPUBrandString << endl;
回答by araqnid
On Linux you can parse /proc/cpuinfo (contains a block of info on each processor) and /proc/meminfo (contains a variety of general memory statistics, including MemTotal).
在 Linux 上,您可以解析 /proc/cpuinfo(包含有关每个处理器的信息块)和 /proc/meminfo(包含各种常规内存统计信息,包括 MemTotal)。
回答by Robert Gould
On Solaris:
在 Solaris 上:
-For memory
- 用于记忆
prtconf | grep Memory
-For CPU
-对于CPU
psrinfo -v | grep MHz
回答by Sweeney
http://en.wikipedia.org/wiki/CPUIDMight help for the CPUID
http://en.wikipedia.org/wiki/CPUID可能对 CPUID 有所帮助
回答by Niall Douglas
The OP wants a CPU clock speed calculating routine portable between Windows and Linux. Here you go:
OP 想要一个可在 Windows 和 Linux 之间移植的 CPU 时钟速度计算例程。干得好:
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
typedef unsigned __int64 usCount;
static usCount GetUsCount()
{
static LARGE_INTEGER ticksPerSec;
static double scalefactor;
LARGE_INTEGER val;
if(!scalefactor)
{
if(QueryPerformanceFrequency(&ticksPerSec))
scalefactor=ticksPerSec.QuadPart/1000000000000.0;
else
scalefactor=1;
}
if(!QueryPerformanceCounter(&val))
return (usCount) GetTickCount() * 1000000000;
return (usCount) (val.QuadPart/scalefactor);
}
#else
#include <sys/time.h>
#include <time.h>
#include <sched.h>
typedef unsigned long long usCount;
static usCount GetUsCount()
{
#ifdef CLOCK_MONOTONIC
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ((usCount) ts.tv_sec*1000000000000LL)+ts.tv_nsec*1000LL;
#else
struct timeval tv;
gettimeofday(&tv, 0);
return ((usCount) tv.tv_sec*1000000000000LL)+tv.tv_usec*1000000LL;
#endif
}
#endif
static usCount usCountOverhead, CPUClockSpeed;
#ifdef __GNUC__
#include "x86intrin.h"
#define __rdtsc() __builtin_ia32_rdtsc()
#endif
static usCount GetClockSpeed()
{
int n;
usCount start, end, start_tsc, end_tsc;
if(!usCountOverhead)
{
usCount foo=0;
start=GetUsCount();
for(n=0; n<1000000; n++)
{
foo+=GetUsCount();
}
end=GetUsCount();
usCountOverhead=(end-start)/n;
}
start=GetUsCount();
start_tsc=__rdtsc();
for(n=0; n<1000; n++)
#ifdef WIN32
Sleep(0);
#else
sched_yield();
#endif
end_tsc=__rdtsc();
end=GetUsCount();
return (usCount)((1000000000000.0*(end_tsc-start_tsc))/(end-start-usCountOverhead));
}
Obviously this only works on x86/x64, and it relies on TSC counting at the same speed as the CPU. If you've done weird overclocking things e.g. on mine I overclock the FSB but downrate the multiplier to keep the core clock at spec, so TSC will count at FSB times the maximum multiplier which is too fast.
显然这仅适用于 x86/x64,并且它依赖于与 CPU 速度相同的 TSC 计数。如果你做了奇怪的超频事情,例如在我的超频上,我会超频 FSB 但降低倍频以保持核心时钟在规格上,所以 TSC 将按 FSB 乘以最大倍频进行计数,这太快了。
To get the best results, before running GetClockSpeed() I'd suggest you run an anti-SpeedStep loop e.g.
为了获得最佳结果,在运行 GetClockSpeed() 之前,我建议您运行一个反 SpeedStep 循环,例如
usCount start;
start=GetUsCount();
while(GetUsCount()-start<3000000000000ULL);
CPUClockSpeed=GetClockSpeed();
Niall
尼尔
回答by GreatCentralSun
For Windows and Win32 C++ Projects:
对于 Windows 和 Win32 C++ 项目:
The above URL and contained article demonstrates 3 different ways to retrieve CPU info on Windows. The source code is at the bottom of the article, is well written, and has three useful classes that you can call from your Win32 C++ code.
上面的 URL 和包含的文章演示了在 Windows 上检索 CPU 信息的 3 种不同方法。源代码位于文章底部,编写得很好,并且包含三个有用的类,您可以从 Win32 C++ 代码中调用它们。