Question

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: " << 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;
}
Was it helpful?

Solution 2

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);
}

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top