开发者

CallNtPowerInformation and GetPwrCapabilities under Linux

开发者 https://www.devze.com 2023-03-30 03:38 出处:网络
I have code that returns information about the running CPUs on an intel-based system under Windows. It does this with the CallNtPowerInformation and GetPwrCapabilities functions. Typical information r

I have code that returns information about the running CPUs on an intel-based system under Windows. It does this with the CallNtPowerInformation and GetPwrCapabilities functions. Typical information returned is the maximum Mhz, current Mhz, maximum idle state, current idle state.

Presumably this is being done with a single instruction, like cpuid.

I want to have similar code that runs under Linux. Any ideas how to do it?

Here is the Windows code that I have:

    /** 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: " 开发者_C百科<< 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;
}


You can find some info by looking around in the proc file system under /proc, for example /proc/cpuinfo or /proc/acpi/processor/.


We finally got some code that does this. It uses the cpuid instruction:

#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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号