【NVIDIA】获取GPU利用率-cpp.md

news2024/11/15 20:55:33

在深度学习推理中,为了更加高效的利用 GPU,在多个推理任务实例中,创建新的实例以及分配到不同的 GPU 设备上,需要关注到当前 GPU 还有多少剩余,以便更好的分配

代码目录

.
├── CMakeLists.txt
├── src
│   └── main.cpp
├── ubuntu_build.sh
└── win10_vs2019_build.bat

windows

前提条件

确保已经安装了 Nvidia 驱动和 CUDA 安装包

nvidia-smi.exe 

可以运行,截图如下:
在这里插入图片描述

nvcc --version

可以运行,截图如下:
在这里插入图片描述

cuda 安装目录

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8

修改 CMakeLists.txt 文件中的 CUDA_ROOT 为 自己安装的目录

NOTE: 注意斜杠 / 和反斜杠 \

构建项目

打开控制台,执行 win10_vs2019_build.bat , 或者直接双击 win10_vs2019_build.bat

NOTE: 前提是安装了 vs2019, “Visual Studio 16 2019”,其他 VS 版本可以同步替换

编译

进入 win10_build 目录,双击 get_gpu_info.sln, 修改编译类型为 Release,编译后生成 get_gpu_info.exe,双击运行即可。

linux

在这里插入图片描述
在这里插入图片描述

构建,编译,执行

bash ubuntu_build.sh

在这里插入图片描述

代码附录

src/main.cpp

/***************************************************************************\
|*                                                                           *|
|*      Copyright 2010-2016 NVIDIA Corporation.  All rights reserved.        *|
|*                                                                           *|
|*   NOTICE TO USER:                                                         *|
|*                                                                           *|
|*   This source code is subject to NVIDIA ownership rights under U.S.       *|
|*   and international Copyright laws.  Users and possessors of this         *|
|*   source code are hereby granted a nonexclusive, royalty-free             *|
|*   license to use this code in individual and commercial software.         *|
|*                                                                           *|
|*   NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE     *|
|*   CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR         *|
|*   IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH      *|
|*   REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF         *|
|*   MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR          *|
|*   PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL,            *|
|*   INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES          *|
|*   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN      *|
|*   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING     *|
|*   OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE      *|
|*   CODE.                                                                   *|
|*                                                                           *|
|*   U.S. Government End Users. This source code is a "commercial item"      *|
|*   as that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting       *|
|*   of "commercial computer  software" and "commercial computer software    *|
|*   documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)   *|
|*   and is provided to the U.S. Government only as a commercial end item.   *|
|*   Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through        *|
|*   227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the       *|
|*   source code with only those rights set forth herein.                    *|
|*                                                                           *|
|*   Any use of this source code in individual and commercial software must  *|
|*   include, in the user documentation and internal comments to the code,   *|
|*   the above Disclaimer and U.S. Government End Users Notice.              *|
|*                                                                           *|
|*                                                                           *|
\***************************************************************************/

#include <stdio.h>
#include <nvml.h>

static const char *convertToComputeModeString(nvmlComputeMode_t mode)
{
    switch (mode)
    {
    case NVML_COMPUTEMODE_DEFAULT:
        return "Default";
    case NVML_COMPUTEMODE_EXCLUSIVE_THREAD:
        return "Exclusive_Thread";
    case NVML_COMPUTEMODE_PROHIBITED:
        return "Prohibited";
    case NVML_COMPUTEMODE_EXCLUSIVE_PROCESS:
        return "Exclusive Process";
    default:
        return "Unknown";
    }
}


int main(int argc, char* argv[])
{
    nvmlReturn_t result;
    unsigned int device_count;

    // 初始化 NVML
    result = nvmlInit();
    if (result != NVML_SUCCESS)
    {
        printf("Failed to initialize NVML: %s\n", nvmlErrorString(result));
        printf("Press ENTER to continue...\n");
        getchar();
        return (int)(result);
    }

    // 获取设备数量
    result = nvmlDeviceGetCount(&device_count);
    if (result != NVML_SUCCESS)
    {
        printf("Failed to get device count: %s\n", nvmlErrorString(result));
        printf("Press ENTER to continue...\n");
        getchar();
        return (int)(result);
    }

    // 遍历设备数量
    printf("\nFound %u device%s, Listing devices:\n", device_count, 
        device_count != 1 ? "s" : "");
    printf("--------------------------------------------------------------\n");
    printf("| Device ID | Device Name\t\t|      pci.busId     | GPU Util | Mem Util |\n");
    for (int i = 0; i < device_count; ++i) 
    {
        nvmlDevice_t device;
        char device_name[NVML_DEVICE_NAME_BUFFER_SIZE];
        nvmlPciInfo_t pci;
        nvmlComputeMode_t compute_mode;

        // 获取设备, 也可以使用其他方式来获取设备
        // nvmlDeviceGetHandleBySerial
        // nvmlDeviceGetHandleByPciBusId
        result = nvmlDeviceGetHandleByIndex(i, &device);
        if (result != NVML_SUCCESS)
        {
            printf("Failed to get handle for device %d: %s\n", i, 
                nvmlErrorString(result));
            continue;
        }        

        // 获取 GPU 设备名称    
        result = nvmlDeviceGetName(device, device_name, NVML_DEVICE_NAME_BUFFER_SIZE);
        if (result != NVML_SUCCESS)
        {
            printf("Failed to get name for device %d: %s\n", i, 
                nvmlErrorString(result));
            continue;
        }

        // pci.busId is very useful to know which device physically you're talking to
        // Using PCI identifier you can also match nvmlDevice handle to CUDA device.
        result = nvmlDeviceGetPciInfo(device, &pci);
        if (result != NVML_SUCCESS)
        {
            printf("Failed to get pci info for device %u: %s\n", i, 
                nvmlErrorString(result));
            continue;
        }

        // 获取 GPU 设备的利用率
        nvmlUtilization_st device_utilization;
        result = nvmlDeviceGetUtilizationRates(device, &device_utilization);
        if (result != NVML_SUCCESS)
        {
            printf("Failed to get utilization for device %d: %s\n", i, 
                nvmlErrorString(result));
            continue;
        }

        printf("|     %d     | %s\t| [%s] |    %u %%  |    %u %%   | \n",
               i, device_name, pci.busId, device_utilization.gpu, device_utilization.memory);
        printf("--------------------------------------------------------------\n");

        // 改变 GPU 状态的简单示例
        result = nvmlDeviceGetComputeMode(device, &compute_mode);
        if (NVML_ERROR_NOT_SUPPORTED == result)
        {
            printf("\t This is not CUDA capable device\n");
        }       
        else if (NVML_SUCCESS != result)
        {
            printf("Failed to get compute mode for device %u: %s\n", i, nvmlErrorString(result));
            continue;
        }
        else
        {
            // try to change compute mode
            printf("\t Changing device's compute mode from '%s' to '%s'\n",
                convertToComputeModeString(compute_mode),
                convertToComputeModeString(NVML_COMPUTEMODE_PROHIBITED));

            result = nvmlDeviceSetComputeMode(device, NVML_COMPUTEMODE_PROHIBITED);
            if (NVML_ERROR_NO_PERMISSION == result)
            {
                printf("\t\t Need root privileges to do that: %s\n", nvmlErrorString(result));
            }        
            else if (NVML_ERROR_NOT_SUPPORTED == result)
            {
                printf("\t\t Compute mode prohibited not supported. You might be running on\n"
                    "\t\t windows in WDDM driver model or on non-CUDA capable GPU\n");
            }
            else if (NVML_SUCCESS != result)
            {
                printf("\t\t Failed to set compute mode for device %u: %s\n", i, nvmlErrorString(result));
                continue;
            }
            else
            {
                printf("\t Restoring device's compute mode back to '%s'\n",
                    convertToComputeModeString(compute_mode));
                result = nvmlDeviceSetComputeMode(device, compute_mode);
                if (NVML_SUCCESS != result)
                {
                    printf("\t\t Failed to restore compute mode for device %u: %s\n", i, nvmlErrorString(result));
                    continue;
                }
            }
        }
    }

    // 关闭 NVML 
    nvmlShutdown();
    if (NVML_SUCCESS != result)
    {
        printf("Failed to shutdown NVML: %s\n", nvmlErrorString(result));
        printf("Press ENTER to continue...\n");
        getchar();
        return (int)(result);
    }

    printf("All done.\n");
    printf("Press ENTER to continue...\n");
    getchar();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
set(PROJECT_NAME get_gpu_info)
project(${PROJECT_NAME})

SET(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Release" FORCE)

add_executable(${PROJECT_NAME} src/main.cpp)

if (WIN32)
    set(CUDA_ROOT "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8")
    include_directories("${CUDA_ROOT}/include/")
    target_link_libraries(${PROJECT_NAME} "${CUDA_ROOT}/lib/x64/nvml.lib")
endif()

if (UNIX)
    set(CUDA_ROOT "/usr/local/cuda")
    include_directories("${CUDA_ROOT}/include/")
    link_directories("${CUDA_ROOT}/lib64/stubs")
    target_link_libraries(${PROJECT_NAME}  libnvidia-ml.so)
endif()

win10_vs2019_build.bat

::在主CMakeLists.txt 里设置opencv和ncnn的路径
set build_dir=win10_build

::删除编译目录
rm -rf %build_dir%

::重新创建编译目录
mkdir %build_dir%

::进入编译目录
cd %build_dir%

::配置, 此处可以利用 -D 添加编译选项
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release ..

::退出目录
cd ..

ubuntu_build.sh

#!/bin/bash

build_dir=ubuntu2204_build

# 删除编译目录
rm -rf ${build_dir}

# 重新创建目录
mkdir ${build_dir}

# 进入目录
cd ${build_dir}

# 构建项目
cmake -DCMAKE_BUILD_TYPE=RELEASE .. 

# 编译
make -j8

# 拷贝出来
cp get_gpu_info ../
cd ..

# 执行
./get_gpu_info

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1106982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

list用法深度解析,一篇文章弄懂list容器各种操作

&#x1f4cb; 前言 &#x1f5b1; 博客主页&#xff1a;在下马农的碎碎念✍ 本文由在下马农原创&#xff0c;首发于CSDN&#x1f4c6; 首发时间&#xff1a;2023/08/10&#x1f4c5; 最近更新时间&#xff1a;2023/08/10&#x1f935; 此马非凡马&#xff0c;房星本是星。向前…

小程序canvas层级过高真机遮挡组件的解决办法

文章目录 问题发现真机调试问题分析问题解决改造代码效果展示 问题发现 在小程序开发中需要上传图片进行裁剪&#xff0c;在实际真机调试中发现canvas层遮挡住了生成图片的按钮。 问题代码 <import src"../we-cropper/we-cropper.wxml"></import> <…

如何使用pytorch定义一个多层感知神经网络模型——拓展到所有模型知识

# 导入必要的库 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, random_split import torchvision.transforms as transforms import torchvision.datasets as datasets# 定义MLP模型 class MLP(nn.Module):def __…

基于Qt QSlider滑动条小项目

QSlider 是滑动条控件,滑动条可以在一个范围内拖动,并将其位置转换为整数 1. 属性和方法 QSlider 继承自 QAbstractSlider,它的绝大多数属性都是从 QAbstractSlider 继承而来的。 2.QSlider信号 - `valueChanged(int value)`: 当滑块的值改变时发出信号,传递当前滑块的值…

mysql检验分区性能的操作

mysql检验分区性能的操作 创建两个结构相同但是一个有分区另外一个没有分区的表 如上图我们给part_tab5创建的分区为1024个&#xff0c;因为mysql中允许最多有1024个分区&#xff1b;之前我测试的是创建8个分区&#xff0c;然后插入500万条数据&#xff0c;然后按照id查询&…

关于页面优化

一、 js优化 js文件内部 1、减少重复代码的使用&#xff0c;精简代码 2、减少请求次数&#xff0c;如果不是需要实时的数据&#xff0c;可以将请求结果缓存在js变量中&#xff0c;后续直接使用变量的值 3、减少不必要的dom操作&#xff0c;例如&#xff1a;用innerHTMl代替do…

小魔推短视频裂变工具,如何帮助实体行业降本增效?

在如今的互联网时代&#xff0c;大多数的实体老板都在寻找不同的宣传方法来吸引客户&#xff0c;现在短视频平台已经成为重中之重的获客渠道之一&#xff0c;而如何在这个日活用户超7亿的平台获取客户&#xff0c;让更多人知道自己的门店、自己的品牌&#xff0c;泽成为了不少老…

uniapp vue3 使用pinia存储数据

import { defineStore } from pinia;export const userInfo defineStore(userInfo, {state: () > {return {userToken: uni.getStorageSync(token) || ,};},actions: {// 添加tokenupdateToken(token: string) {uni.setStorageSync(token, token);this.userToken token}} …

Apache Doris (四十三): Doris数据更新与删除 - Update数据更新

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. Update数据更新原理

全面解决找不到vcruntime140_1.dll无法执行此代码问题的5方法

vcruntime140_1.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2015 Redistributable的一部分。当计算机中缺少这个文件时&#xff0c;可能会导致一些应用程序无法正常运行&#xff0c;从而影响我们的工作和生活。 一、问题场景 1. 在使用Windows操作系统的过程…

QTday02(常用类、UI界面下的开发、信号与槽)

今日任务 1. 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#x…

出差学小白知识No5:ubuntu连接开发板|上传源码包|板端运行的环境部署

1、ubuntu连接开发板&#xff1a; 在ubuntu终端通过ssh协议来连接开发板&#xff0c;例如&#xff1a; ssh root<IP_address> 即可 这篇文章中也有关于如何连接开发板的介绍&#xff0c;可以参考SOC侧跨域实现DDS通信总结 2、源码包上传 通过scp指令&#xff0c;在ub…

1018hw

#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);//窗口名this->setWindowTitle("QQ");this->setWindowIcon(QIcon(&q…

位段——(详细图解,保姆宗师级教程,包会,从基础概念到精通实战应用)

位段——大项目中结构体节省空间之手段 学习目标&#xff1a; 位段是什么 位段的内存分配 位段的平台局限性和应用 学习内容&#xff1a; 1.位段是什么 C中的位段&#xff08;Bit fields&#xff09;是一种用于有效利用内存的特性&#xff0c;可以在结构体中定义成员变量的…

朴素贝叶斯(基于概率论)

释义 贝叶斯定理是“由果溯因”的推断&#xff0c;所以计算的是"后验概率" 其中&#xff1a; P(A|B) 表示在事件 B 已经发生的条件下&#xff0c;事件 A 发生的概率。 P(B|A) 表示在事件 A 已经发生的条件下&#xff0c;事件 B 发生的概率。 P(A) 和 P(B) 分别表示事…

贴片电阻材质:了解电子元件的核心构成 | 百能云芯

在现代电子设备中&#xff0c;贴片电阻是一类至关重要的 passives 元件&#xff0c;广泛用于各种电路和应用中。贴片电阻的性能取决于多个因素&#xff0c;其中材质是其中之一。云芯将带您深入探讨贴片电阻的不同材质&#xff0c;探讨不同材质对电子元件性能的影响&#xff0c;…

深入理解算法:从基础到实践

深入理解算法&#xff1a;从基础到实践 1. 算法的定义2. 算法的特性3. 算法的分类按解决问题的性质分类&#xff1a;按算法的设计思路分类&#xff1a; 4. 算法分析5. 算法示例a. 搜索算法示例&#xff1a;二分搜索b. 排序算法示例&#xff1a;快速排序c. 动态规划示例&#xf…

【考研数学】概率论与数理统计 —— 第六章 | 数理统计基本概念(1,基本概念)

文章目录 引言一、基本概念1.1 总体1.2 样本1.3 统计量1.4 顺序统计量 写在最后 引言 以前学概率论的时候&#xff0c;不知道后面的数理统计是什么&#xff0c;所以简称都把后面的省略掉了。现在接触的学科知识多了&#xff0c;慢慢就对数理统计有了直观印象。 尤其是第一次参…

刷题日记1

最近在用JavaScript刷动态规划的题组&#xff0c;刷了一半感觉只刷题不写笔记的话印象没那么深刻&#xff0c;所以从今天开始来记录一下刷题情况。 力扣T300 300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而…

超实用!了解github的热门趋势和star排行是必须得!

在当今的技术领域中&#xff0c;GitHub 已经成为了开发者们分享和探索代码的重要平台。作为全球最大的开源社区&#xff0c;GitHub上托管了数以亿计的项目&#xff0c;其中包括了各种各样的技术栈和应用。对于开发者来说&#xff0c;了解GitHub上的热门趋势和star排行是非常重要…