【问题标题】:Get temperature from NVidia GPU using NVAPI使用 NVAPI 从 NVidia GPU 获取温度
【发布时间】:2013-03-29 19:14:16
【问题描述】:

过去几天我一直在尝试使用 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 正在初始化,它可以找到我的 GTX680 GPU,但它不会返回温度

【问题讨论】:

  • 打印一个长整数,printf("Temp: %l C\n") 应该是printf("Temp: %li C\n")。 l 只是一个长度说明符,您还应该指定它影响的类型。看看here
  • 非常感谢,我想我应该更好地检查我的类型

标签: c++ gpu nvidia temp nvapi


【解决方案1】:

printf 对其传递的参数的大小和类型非常敏感。

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

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

【讨论】:

  • 不应该 static_cast&lt;unsigned&gt; 是 static_cast&lt;unsigned int&gt;,因为这个问题被标记为 C++? unsigned 本身在 C 中是一个有效的说明符,在 C++ 中它不再是。另请参阅我对 OP 问题的评论,因为此答案与 OP 的问题没有直接关系。
  • @TomKnapen 它仍然是 C++ 中的有效类型。见this reference
  • 是的,我刚刚进行了快速测试,发现它仍然有效。我已经在查看 here 以了解如何在我的评论中删除文本。
【解决方案2】:

我认为问题在于您需要通过以下方式设置热设置:

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】:

    您的代码几乎可以正常工作,只是这些行有错别字;)

    (!ret == NVAPI_OK)
    

    将它们更改为:

    (ret != NVAPI_OK)
    

    【讨论】:

      【解决方案4】:

      您已经能够获得正确的 thermo.sensor[0].currentTemp 值,

      只是您在打印时弄错了。

      请看 Nvapi 中的 thermo.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 位整数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-07
        • 2020-10-18
        • 2021-03-29
        • 1970-01-01
        • 2021-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多