CallNtPowerInformation и GetPwrCapabilities под Linux - PullRequest
2 голосов
/ 23 августа 2011

У меня есть код, который возвращает информацию о запущенных процессорах в системе на базе Intel под Windows. Это делается с помощью функций CallNtPowerInformation и GetPwrCapabilities. Типичная возвращаемая информация - это максимальный МГц, текущий МГц, максимальный режим ожидания, текущий режим ожидания.

Предположительно, это делается с помощью одной инструкции, например cpuid.

Я хочу иметь подобный код, который работает под Linux. Есть идеи как это сделать?

Вот код Windows, который у меня есть:

    /** cpustat.h -- Header for cpustat.cpp.                                                                                 
     * Copyright (c) 2004 Brad Fish (brad.fish@gmail.com).                                                                   
     */

    #if !defined(MAIN_H)
    #define MAIN_H

    #include <windows.h>

    // missing Windows processor power information struct                                                                    
    typedef struct _PROCESSOR_POWER_INFORMATION {
      ULONG  Number;
      ULONG  MaxMhz;
      ULONG  CurrentMhz;
      ULONG  MhzLimit;
      ULONG  MaxIdleState;
      ULONG  CurrentIdleState;
    } PROCESSOR_POWER_INFORMATION , *PPROCESSOR_POWER_INFORMATION;

    int main (int argc, char *argv[]);

    #endif  // MAIN_H                                                                                                        

#include "cpustat.h"
#include <cstdio>
#include <vector>
#include <iostream>

extern "C" {
#include <powrprof.h>
}
int main (int argc, char *argv[])
{
    typedef std::vector<PROCESSOR_POWER_INFORMATION> PPIVector;

    SYSTEM_INFO sys_info;
    PPIVector ppis;
    SYSTEM_POWER_CAPABILITIES spc;

    // find out how many processors we have in the system                                                                    
    GetSystemInfo(&sys_info);
    ppis.resize(sys_info.dwNumberOfProcessors);

    // get CPU stats                                                                                                         
    if (CallNtPowerInformation(ProcessorInformation, NULL, 0, &ppis[0],
        sizeof(PROCESSOR_POWER_INFORMATION) * ppis.size()) != ERROR_SUCCESS)
    {
        perror("main: ");
        return -1;
    }

    // print out CPU stats                                                                                                   
    for (PPIVector::iterator it = ppis.begin(); it != ppis.end(); ++it)
    {
        std::cout << "stats for CPU " << it->Number << ':' << std::endl;
        std::cout << "  maximum MHz: " << it->MaxMhz << std::endl;
        std::cout << "  current MHz: " << it->CurrentMhz << std::endl;
        std::cout << "  MHz limit: " << it->MhzLimit << std::endl;
        std::cout << "  maximum idle state: " << it->MaxIdleState << std::endl;
        std::cout << "  current idle state: " << it->CurrentIdleState <<
            std::endl;
    }

    // get system power settings                                                                                             
    if (!GetPwrCapabilities(&spc))
    {
        perror("main: ");
        return -2;
    }

    // print power settings                                                                                                  
    std::cout << "system power capabilities:" << std::endl;
    std::cout << "  processor throttle: " <<
        (spc.ProcessorThrottle ? "enabled" : "disabled") << std::endl;
    std::cout << "  processor minimum throttle: " <<
        static_cast<int>(spc.ProcessorMinThrottle) << '%' << std::endl;
    std::cout << "  processor maximum throttle: " <<
        static_cast<int>(spc.ProcessorMaxThrottle) << '%' << std::endl;
}

Ответы [ 2 ]

0 голосов
/ 30 сентября 2013

Мы наконец-то получили код, который делает это. Используется инструкция cpuid:

#include <stdint.h>
#include <stdio.h>
#include <limits.h>

#define cpuid(id) __asm__( "cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(id), "b"(0), "c"(0), "d"(0))
#define b(val, base, end) ((val << (__WORDSIZE-end-1)) >> (__WORDSIZE-end+base-1))

int main(int argc, char **argv)
{
        unsigned long eax, ebx, ecx, edx;

        cpuid(0);
        printf("identification: \"%.4s%.4s%.4s\"\n", (char *)&ebx, (char *)&edx, (char *)&ecx);

        printf("cpu information:\n");

        cpuid(1);
        printf(" family %ld model %ld stepping %ld efamily %ld emodel %ld\n",
                        b(eax, 8, 11), b(eax, 4, 7), b(eax, 0, 3), b(eax, 20, 27), b(eax, 16, 19));
        printf(" brand %ld cflush sz %ld*8 nproc %ld apicid %ld\n",
                        b(ebx, 0, 7), b(ebx, 8, 15), b(ebx, 16, 23), b(ebx, 24, 31));

        cpuid(0x80000006);
        printf("L1 cache size (per core): %ld KB\n", b(ecx, 16, 31));

        return(0);
}
0 голосов
/ 26 августа 2011

Информацию можно найти, оглянувшись в файловой системе proc под /proc, например /proc/cpuinfo или /proc/acpi/processor/.

...