Программно получить информацию о процессоре от Mac OS X - PullRequest
8 голосов
/ 12 мая 2009

Мое приложение, работающее в Mac OS X, которое нуждается в получении сведений о машине, на которой оно запущено, для получения сведений о системе. Один из элементов, который мне нужен, - это информация о процессоре (ах), установленном на компьютере.

Мой код в настоящее время работает, но это далеко не идеальное решение, на самом деле я считаю его плохим решением, но мне не повезло в поиске лучшего.

Информация, которую я сообщаю в настоящее время и после некоторого форматирования, выглядит следующим образом:

Процессор: Intel Core 2 Duo 2,1 ГГц, семейство 6, модель 23, степпинг 6

Вся информация, которую я получаю, через утилиты командной строки, вызываемые из popen (). Читаемая часть описания процессора берется из выходных данных команды "system_profiler", а значения Family, Model и Stepping берутся из команды "sysctl".

Эти утилиты командной строки должны откуда-то получать информацию. Мне интересно, есть ли программный интерфейс для получения этой же информации?


Связанный:

Ответы [ 5 ]

8 голосов
/ 05 августа 2010

Используйте 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 из командной строки.

7 голосов
/ 13 мая 2009

Вам нужно взглянуть на API IOKit. Приложение IORegistryExplorer (часть стандартной установки devtools) поможет вам найти то, что вы ищете.

Например, на моем MacBook Pro в IORegistryExplorer я выбираю «IODeviceTree» из раскрывающегося списка в верхнем левом углу окна, и я вижу два ЦП в древовидном представлении ниже. Выбор любого из них дает мне следующую информацию:

IORegistryExplorer screenshot http://blog.alanquatermain.net/images/IORegistryExplorer-CPUs.png

«шина-частота», «частота-частота» и «частота-база» - это все 32-битные целочисленные обертки в объектах данных, и поэтому для их интерпретации они должны быть заменены байтами (машинные слова в младшем порядке) и определите следующие значения:

  • частота шины: 1064000000 Гц => 1,064 ГГц
  • тактовая частота: 2530000000 Гц => 2,53 ГГц
  • частота: 1000000000 Гц => 1,0 ГГц

Однако, если вы читаете их через IOKit, вы получите CFDataRef и можете просто скопировать байты в свой собственный uint32_t, например:

uint32_t bus_frequency = 0;
CFDataGetBytes( theData, (UInt8 *) &bus_frequency, sizeof(uint32_t) );

Далее вы можете получить информацию о процессоре, используя вызов NXArchInfo(), полученный путем включения <mach-o/arch.h>. Это вернет структуру, содержащую коды типов и подтипов процессора, а также имена и описания C-строк. Если это не включает в себя пошаговый идентификатор, единственный способ, которым я могу придумать, чтобы получить это (от макушки головы), - через инструкцию 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. Теоретически , который будет охватывать все базы.

5 голосов
/ 12 мая 2009

sysctl(3), вероятно, хорошее место для начала. Вы, вероятно, хотите материал, определенный селекторами CTL_HW.

0 голосов
/ 04 июня 2019

вариант метода 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.

0 голосов
/ 13 мая 2010

Если вам нужна информация о процессоре, используйте инструкцию cpuid (в C __asm ​​cpuid). Он предоставляет всю возможную информацию о процессоре, включая его семейство, модель, компанию, количество ядер и т. Д. Прежде всего все API используют эту инструкцию для получения информации о процессоре. Вы можете получить подробную информацию о CPUID в Интернете, включая пример кода и учебные пособия.

...