使用NVAPI从NVidia GPU获取温度

4

我最近几天一直在尝试使用C++获取我的GPU的温度

使用NVAPI,我有以下代码

#include "stdafx.h"
#include "nvapi.h"


int _tmain(int argc, _TCHAR* argv[])
{
    NvAPI_Status ret = NVAPI_OK;
    int i=0;

    NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS*2] = {0};

    ret = NvAPI_Initialize();

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_Initialize: %s\n", string);
    }

    NvAPI_ShortString ver;

    NvAPI_GetInterfaceVersionString(ver);
    printf("NVAPI Version: %s\n", ver);

    NvU32 cnt;

    NvPhysicalGpuHandle phys;

    ret = NvAPI_EnumPhysicalGPUs(&phys, &cnt);

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_EnumPhysicalGPUs: %s\n", string);
    }

    NvAPI_ShortString name;

    NV_GPU_THERMAL_SETTINGS thermal;

    ret = NvAPI_GPU_GetFullName(phys, name);
    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_GPU_GetFullName: %s\n", string);
    }

    printf("Name: %s\n", name);
    thermal.version =NV_GPU_THERMAL_SETTINGS_VER;
    ret = NvAPI_GPU_GetThermalSettings(phys,0, &thermal);

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_GPU_GetThermalSettings: %s\n", string);
    }

    printf("Temp: %l C\n", thermal.sensor[0].currentTemp);

    return 0;
}

我得到的输出是
NVAPI Version: NVidia Complete Version 1.10
Name: GeForce GTX 680
Temp:  C

因此,NVAPI正在初始化,并且可以找到我的GPU,它是GTX680,但它不会返回温度。


要打印一个长整型数,应该使用 printf("Temp: %li C\n") 而不是 printf("Temp: %l C\n")。其中 l 只是一个长度说明符,你还需要指定它所影响的类型。可以在这里查看更多信息。 - Tom Knapen
非常感谢您,我想我应该更好地检查我的类型。 - Shuttleu
4个回答

3

我认为问题在于你需要按以下方式设置热量参数:

NV_GPU_THERMAL_SETTINGS ThermalInfo;
ThermalInfo.version = NV_GPU_THERMAL_SETTINGS_VER_2;
ThermalInfo.sensor[0].controller = NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL;
ThermalInfo.sensor[0].target = NVAPI_THERMAL_TARGET_GPU;

此外,您还应该写:
NvPhysicalGpuHandle  nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS];

因为你可能会破坏内存。(请注意查看随NVAPI提供的文档中的NvAPI_EnumPhysicalGPUs)。


3

printf 很敏感于它所传递的参数的大小和类型。

由于 currentTemp 是固定为32位无符号数(而C ++不保证 printf 喜欢的类型具有特定的位数),请将其转换为 printf 可以预期的类型。

printf("Temp: %u C\n", static_cast<unsigned>(thermal.sensor[0].currentTemp) );

由于这个问题被标记为C ++,所以static_cast<unsigned>不应该是static_cast<unsigned int>吗?在C中,unsigned本身是一个有效的限定符,在C ++中不再是。此外,请参阅我的评论OP的问题,因为这个答案与OP的问题没有直接关系。 - Tom Knapen
@TomKnapen 在 C++ 中它仍然是一个有效的类型。请参见此参考资料 - Drew Dormann
是的,我刚跑了一个快速测试并发现它仍然有效。我已经在这里查看如何在我的评论中使用删除线格式:http://stackoverflow.com/editing-help#comment-formatting - Tom Knapen

0

你的代码差不多可以运行了,只是这些行有拼写错误 ;)

(!ret == NVAPI_OK)

将它们更改为:

(ret != NVAPI_OK)

0

你已经能够正确获取thermal.sensor[0].currentTemp的值了,

只是在打印时出现了错误。

请查看Nvapi中的thermal.sensor结构:

struct
{
    NV_THERMAL_CONTROLLER       controller;         //!< internal, ADM1032, MAX6649...
    NvS32                       defaultMinTemp;     //!< Minimum default temperature value of the thermal sensor in degree Celsius
    NvS32                       defaultMaxTemp;     //!< Maximum default temperature value of the thermal sensor in degree Celsius
    NvS32                       currentTemp;        //!< Current temperature value of the thermal sensor in degree Celsius
    NV_THERMAL_TARGET           target;             //!< Thermal sensor targeted - GPU, memory, chipset, powersupply, Visual Computing Device, etc
} sensor[NVAPI_MAX_THERMAL_SENSORS_PER_GPU];

这表明NvS32 currentTemp是带符号的32位整数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接