windows环境下C++获取硬盘利用率,内存利用率,CPU利用率,英伟达显卡GPU利用率(代码亲测有效)

学校项目有此需求,百度整合,供有缘人使用
网上资料较杂,这个版本是我从网上整合出来,经过实际项目验收,然后出于学校项目保密的性质,把这个小轮子从项目中拆出来供大家使用

//头文件 monitor.h
#include <windows.h>
#include <tchar.h>
#include<iostream>
#include <stdio.h>
#include "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.2\\include\\nvml.h"

#define DIV 1024
#define GB(x) (((x).HighPart << 2) + ((DWORD)(x).LowPart) / 1024.0 / 1024.0 / 1024.0)
// Specify the width of the field in which to print the numbers. 
// The asterisk in the format specifier "%*I64d" takes an integer 
// argument and uses it to pad and right justify the number.
#define WIDTH 7

//continuous sending HeartBeat, HardwareStatus, and SoftwareStatus
typedef unsigned char byte;
class Monitor
{
public:
    void getHastate(byte* cpuusage, byte* gpuusage, byte* hduusage, ushort* hdremain, byte* memusage);
private:
    byte GetCpuRate_byte();
    byte GetGpuRate_byte();
    std::pair<byte, ushort> GetDiskRate_byte();
    byte GetMemoryRate_byte();
};
//对应源文件 monitor.cpp
#include "monitor.h"
#pragma comment(lib, "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.2\\lib\\x64\\nvml.lib")

__int64 CompareFileTime(FILETIME time1, FILETIME time2)
{
    __int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
    __int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;

    return (b - a);
}

byte Monitor::GetCpuRate_byte() {

    HANDLE hEvent;
    BOOL res;
    FILETIME preidleTime;
    FILETIME prekernelTime;
    FILETIME preuserTime;
    FILETIME idleTime;
    FILETIME kernelTime;
    FILETIME userTime;

    res = GetSystemTimes(&idleTime, &kernelTime, &userTime);
    preidleTime = idleTime;
    prekernelTime = kernelTime;
    preuserTime = userTime;

    hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); // 初始值为 nonsignaled ,并且每次触发后自动设置为nonsignaled  

    WaitForSingleObject(hEvent, 1000);
    res = GetSystemTimes(&idleTime, &kernelTime, &userTime);

    __int64 idle = CompareFileTime(preidleTime, idleTime);
    __int64 kernel = CompareFileTime(prekernelTime, kernelTime);
    __int64 user = CompareFileTime(preuserTime, userTime);

    __int64 cpu = (kernel + user - idle) * 100 / (kernel + user);
    __int64 cpuidle = (idle) * 100 / (kernel + user);

    preidleTime = idleTime;
    prekernelTime = kernelTime;
    preuserTime = userTime;
    double cpu_use = cpu;
    return cpu_use;
}


byte Monitor::GetGpuRate_byte() {
    nvmlReturn_t result;
    unsigned int device_count, i;
    // First initialize NVML library
    result = nvmlInit();

    result = nvmlDeviceGetCount(&device_count);
    if (NVML_SUCCESS != result)
    {
        std::cout << "Failed to query device count: " << nvmlErrorString(result);
    }
    //std::cout << "Found" << device_count << " device" << endl;

    //std::cout << "Listing devices:";
    for (i = 0; i < device_count; i++)
    {
        nvmlDevice_t device;
        char name[NVML_DEVICE_NAME_BUFFER_SIZE];
        nvmlPciInfo_t pci;
        result = nvmlDeviceGetHandleByIndex(i, &device);
        if (NVML_SUCCESS != result) {
            //std::cout << "get device failed " << endl;
        }
        result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE);
        if (NVML_SUCCESS != result) {
            //std::cout << "GPU name: " << name << endl;
        }
        //使用率
        nvmlUtilization_t utilization;
        result = nvmlDeviceGetUtilizationRates(device, &utilization);
        if (NVML_SUCCESS == result)
        {
            return ((byte)utilization.gpu);
            //std::cout << "----- 使用率 ----- " << endl;
            //std::cout << "GPU 使用率: " << utilization.gpu << endl;
            //std::cout << "显存使用率 " << utilization.memory << endl;
        }
    }
    return 0;
}


std::pair<byte, ushort> Monitor::GetDiskRate_byte() {
    
    ULARGE_INTEGER FreeBytesAvailableC, TotalNumberOfBytesC, TotalNumberOfFreeBytesC;
    ULARGE_INTEGER FreeBytesAvailableD, TotalNumberOfBytesD, TotalNumberOfFreeBytesD;
    ULARGE_INTEGER FreeBytesAvailableE, TotalNumberOfBytesE, TotalNumberOfFreeBytesE;
    ULARGE_INTEGER FreeBytesAvailableF, TotalNumberOfBytesF, TotalNumberOfFreeBytesF;

    GetDiskFreeSpaceEx(_T("C:"), &FreeBytesAvailableC, &TotalNumberOfBytesC, &TotalNumberOfFreeBytesC);
    GetDiskFreeSpaceEx(_T("D:"), &FreeBytesAvailableD, &TotalNumberOfBytesD, &TotalNumberOfFreeBytesD);
    GetDiskFreeSpaceEx(_T("E:"), &FreeBytesAvailableE, &TotalNumberOfBytesE, &TotalNumberOfFreeBytesE);
    GetDiskFreeSpaceEx(_T("F:"), &FreeBytesAvailableF, &TotalNumberOfBytesF, &TotalNumberOfFreeBytesF);
    float totalHardDisk = GB(TotalNumberOfBytesC) + GB(TotalNumberOfBytesD) + GB(TotalNumberOfBytesE) + GB(TotalNumberOfBytesF);
    float freeHardDisk = GB(TotalNumberOfFreeBytesC) + GB(TotalNumberOfFreeBytesD) + GB(TotalNumberOfFreeBytesE) + GB(TotalNumberOfFreeBytesF);

    double hardDiskUsage = (1 - freeHardDisk / totalHardDisk) * 100;
    auto res = std::make_pair((byte)hardDiskUsage, ushort(freeHardDisk));
    return res;
}

byte Monitor::GetMemoryRate_byte() {

    MEMORYSTATUSEX statex;

    statex.dwLength = sizeof(statex);

    GlobalMemoryStatusEx(&statex);
    double memoryUse = statex.dwMemoryLoad;
    return memoryUse;
}

void Monitor::getHastate(byte* cpuusage, byte* gpuusage,
    byte* hduusage, ushort* hdremain, byte* memusage)
{
    *cpuusage = GetCpuRate_byte();
    *gpuusage = GetGpuRate_byte();
    auto hdu = GetDiskRate_byte();
    *hduusage = hdu.first;
    *hdremain = hdu.second;
    *memusage = GetMemoryRate_byte();
}

其中需要注意的就是关于GPU相关信息的获取,涉及到英伟达显卡的头文件和那个lib在显卡的默认安装路径就可以找得到,如果不同的话直接替换一下路径即可
然后还需要注意的一点是,需要在C:\Program Files\NVIDIA Corporation\NVSMI目录下有一个nvml.dll,可能需要把这个动态库放到编译出来的可执行文件的同级目录中
关于这个操作的参考链接如下:
nvml.dll找不到怎么办
windows平台关于GPU信息的获取 C++
可能会有小错误,是因为我从整个项目里粘出来的时候误删了…

另外一份调试通过的获取GPU利用率的代码

#include <cuda_runtime.h>
#include <iostream>
#include <memory>
#include <string>
//#pragma comment(lib, "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.2\\lib\\x64\\cudart.lib")
//注释掉的东西不写也可以,在编译器中设置好引用的lib即可

void checkGpuMem() {
    size_t avail;
    size_t total;
    cudaMemGetInfo(&avail, &total);
    size_t used = total - avail;
    std::cout << "=================" << std::endl;
    std::cout << "Device memory used: " << used << std::endl;
    std::cout << "Total memory  used: " << total << std::endl;
    std::cout << "=================" << std::endl;
}

int main() {
    int deviceCount = 0;
    cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
    // This function call returns 0 if there are no CUDA capable devices.
    if (deviceCount == 0) {
        printf("There are no available device(s) that support CUDA\n");
    }
    else {
        printf("Detected %d CUDA Capable device(s)\n", deviceCount);
    }
    checkGpuMem();
    getchar();
}
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巴塞罗那的风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值