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);
}
精彩评论