我的应用程序在Mac OS X上运行,需要检索有关正在运行的计算机的详细信息以报告系统信息。我需要的其中一项是有关计算机中安装的处理器的详细信息。
我的代码目前有效,但远非理想的解决方案,事实上我认为这是一个糟糕的解决方案,但我没有找到更好的解决方案。
我目前报告的信息以及一些格式化后的信息如下:
处理器:Intel Core 2 Duo 2.1 GHz,Family 6 Model 23 Stepping 6
我得到的所有信息都是通过popen()调用的命令行实用程序。处理器描述的可读部分取自“system_profiler”命令输出,Family,Model和Stepping值取自“sysctl”命令。
这些命令行实用程序必须从某处获取信息。 我想知道是否有可用的程序界面来获取相同的信息?
相关:
答案 0 :(得分:8)
使用sysctlbyname
而不是sysctl
,例如
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/sysctl.h>
uint64_t get_cpu_freq(void)
{
uint64_t freq = 0;
size_t size = sizeof(freq);
if (sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0) < 0)
{
perror("sysctl");
}
return freq;
}
您可以通过从命令行查看systctlbyname
的输出来获取可以传递给sysctl -a
的名称列表。
答案 1 :(得分:7)
您需要查看IOKit API。 IORegistryExplorer应用程序(标准devtools安装的一部分)将帮助您找到您要查找的内容。
例如,在我的MacBook Pro上,在IORegistryExplorer中,我从窗口左上角的下拉菜单中选择“IODeviceTree”,我可以在下面的树视图中看到两个CPU。选择任何一个都会获得以下信息:
IORegistryExplorer screenshot http://blog.alanquatermain.net/images/IORegistryExplorer-CPUs.png
'bus-frequency'和'clock-frequency','timebase-frequency'都是数据对象中的32位整数包装器,因此必须进行字节交换才能解释(little-endian i386机器字) ,并确定以下值:
如果您通过IOKit读取这些内容,那么您将获得CFDataRef,并且可以将字节复制到您自己的uint32_t中,如下所示:
uint32_t bus_frequency = 0;
CFDataGetBytes( theData, (UInt8 *) &bus_frequency, sizeof(uint32_t) );
接下来,您可以使用通过加入NXArchInfo()
获得的<mach-o/arch.h>
来获取处理器信息。这将返回一个包含cpu类型和子类型代码以及C字符串名称和描述的结构。如果那不包括步进ID,我能想到的唯一方法就是通过CPUID指令来获取它(在我的脑海中)。创建.s和.h文件,并输入以下代码:
.s文件:
#ifdef __i386__ || __x86_64__
.macro ENTRY
.text
.private_extern $0
.align 4, 0x90
$0:
.endmacro
// __private_extern__ unsigned long GetCPUSteppingID( void )
ENTRY _GetCPUSteppingID
push %ebp // store existing frame pointer
mov %esp,%ebp // make a new frame pointer from stack pointer
#if __x86_64__
push %rbx
#endif
push %ebx // we save %ebx because the cpuid instruction
// will overwrite it, and it's expected
// to be unchanged in the caller after
// calling another function
movl $1,%eax // fetch cpu info
cpuid // stepping-id is in low 4 bits of %edx now
and $0x0000000f,%edx // clear out everything we don't want
#if __x86_64__
mov %edx,%rax // %rax is 64-bit arch result register
#else
mov %edx,%eax // %eax is 32-bit arch result register
#endif
pop %ebx // restore saved value of %ebx
#if __x86_64__
pop %rbx // restore saved value of %rbx
#endif
leave // restores prior stack frame from %ebp
ret // returns to caller
#endif // __i386__ || __x86_64__
.h文件:
#ifndef __GET_STEPPING_ID__
#define __GET_STEPPING_ID__
/* unsigned long is register-sized on both 32-bit and 64-bit OS X */
__private_extern__ unsigned long GetSteppingID( void );
#endif /* __GET_STEPPING_ID__ */
请注意,我不确定上面的x86_64位;从理论上讲,我输入的内容将确保相同的代码编译为64位,并且在这种情况下将返回64位值。它还将保存/恢复%rbx寄存器,即64位版本的%ebx寄存器。 理论上将涵盖所有基础。
答案 2 :(得分:5)
sysctl(3)
可能是个好地方。您可能想要CTL_HW
选择器定义的内容。
答案 3 :(得分:0)
如果您特别需要CPU信息,请使用cpuid(在C __asm cpuid中)指令。它提供了CPU的所有可能信息,包括其系列,型号,公司,内核数量等。主要是所有API都使用此指令来检索CPU信息。您可以在Web上获得有关CPUID的详细信息,包括示例代码和教程。
答案 4 :(得分:0)
Paul R方法的一种变体
#include <iostream>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/sysctl.h>
void show_cpu_info(void)
{
char buffer[1024];
size_t size=sizeof(buffer);
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &size, NULL, 0) < 0) {
perror("sysctl");
}
std::cout << buffer << '\n';
}
将直接显示类似Intel(R) Core(TM)2 Duo CPU L9400 @ 1.86GHz
的内容。