簡體   English   中英

以編程方式從Mac OS X獲取處理器詳細信息

[英]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機器字),然后才能正常工作得出以下值:

  • 總線頻率:1064000000 Hz => 1.064 GHz
  • 時鍾頻率:2530000000 Hz => 2.53 GHz
  • 時基頻率:1000000000 HZ => 1.0 GHz

但是,如果您是通過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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM