Linux 下的 CallNtPowerInformation 和 GetPwrCapativity

发布于 2024-12-01 04:11:46 字数 3825 浏览 2 评论 0原文

我的代码可以返回有关 Windows 下基于 Intel 的系统上正在运行的 CPU 的信息。它通过 CallNtPowerInformation 和 GetPwrCapability 函数来完成此操作。返回的典型信息是最大Mhz、当前Mhz、最大空闲状态、当前空闲状态。

据推测,这是通过单个指令完成的,例如 cpuid。

我想要在 Linux 下运行类似的代码。有什么想法如何去做吗?

这是我的 Windows 代码:

    /** cpustat.h -- Header for cpustat.cpp.                                                                                 
     * Copyright (c) 2004 Brad Fish ([email protected]).                                                                   
     */

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

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 ([email protected]).                                                                   
     */

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜是你 2024-12-08 04:11:46

您可以通过查看 /proc 下的 proc 文件系统找到一些信息,例如 /proc/cpuinfo/proc /acpi/处理器/

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

你的笑 2024-12-08 04:11:46

我们终于得到了一些执行此操作的代码。它使用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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文