[英]Programmatically get processor details from Mac OS X
我的應用程序在Mac OS X上運行,需要檢索有關其所運行機器的詳細信息以報告系統信息。 我需要的項目之一是有關計算機中安裝的處理器的詳細信息。
我的代碼目前可以運行,但遠非理想的解決方案,實際上我認為這是一個糟糕的解決方案,但是我沒有找到更好的解決方案的運氣。
經過一些格式化后,我當前報告的信息如下所示:
處理器:Intel Core 2 Duo 2.1 GHz,Family 6 Model 23 Steping 6
我獲得的所有信息都是通過從popen()調用的命令行實用程序獲得的。 處理器描述的可讀部分來自“ system_profiler”命令輸出,而Family,Model和Stepping值則來自“ sysctl”命令。
這些命令行實用程序必須從某處獲取信息。 我想知道是否有可用的編程界面來獲取相同的信息?
有關:
使用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
的輸出,可以獲得可以傳遞給systctlbyname
的名稱的列表。
您需要查看IOKit API。 IORegistryExplorer應用程序(標准devtools安裝的一部分)將幫助您找到所需的內容。
例如,在MacBook Pro的IORegistryExplorer中,我從窗口左上角的下拉菜單中選擇“ IODeviceTree”,然后在下面的樹狀視圖中可以看到兩個CPU。 選擇任何一個都會為我提供以下信息:
IORegistryExplorer屏幕截圖http://blog.alanquatermain.net/images/IORegistryExplorer-CPUs.png
“總線頻率”和“時鍾頻率”以及“時基頻率”都是數據對象中的32位整數包裝器,因此必須在此處進行字節交換以解釋(小尾數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位值。 它還將保存/恢復%ebx寄存器的64位版本%rbx寄存器。 從理論上講 ,它將覆蓋所有基礎。
sysctl(3)
可能是一個不錯的起點。 您可能需要CTL_HW
選擇器定義的CTL_HW
。
如果您特別想要CPU信息,則使用cpuid(在C __asm cpuid中)指令。 它提供了CPU的所有可能信息,包括其系列,型號,公司,內核數等。主要是,所有API均使用此指令來檢索CPU信息。 您可以在Web上獲取有關CPUID的詳細信息,包括示例代碼和教程。
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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.