【问题标题】:use python ctypes to interface with nvapi (follow up with demonstration code)使用 python ctypes 与 nvapi 交互(跟进演示代码)
【发布时间】:2011-09-04 04:05:11
【问题描述】:

这是我上一个问题的后续:help with python ctypes and nvapi

我正在发布另一个问题,因为我已经在上一个问题中选择了一个答案,并且问题现在已经改变了方向。

使用 python,我正在尝试查询 nvapi.dll 以获取我的 gpu 使用值。

这就是您在 C# 中的操作方式(如下所示):http://code.google.com/p/open-hardware-monitor/source/browse/trunk/Hardware/Nvidia/NVAPI.cs

因为我只需要一小部分功能,我并不想换成另一种语言。我认为 ctypes 应该能够做到这一点......我只是不知道该怎么做。我以前从未真正使用过 Python ctypes。

为了查询 gpu 使用情况,我首先需要调用 NvAPI_Initialize 函数。还必须使用查询接口来引用函数:

from ctypes import *
nvapi = WinDLL("nvapi.dll")
nvapi_QueryInterface = nvapi.nvapi_QueryInterface

使用上面的代码,我可以访问 nvapi_QueryInterface,但我不知道如何复制这部分:

private static void GetDelegate<T>(uint id, out T newDelegate)
  where T : class
{
    IntPtr ptr = nvapi_QueryInterface(id);
    if (ptr != IntPtr.Zero)
    {
        newDelegate =
          Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
    }
    else
    {
        newDelegate = null;
    }
}

引用初始化和使用函数:

GetDelegate(0x0150E828, out NvAPI_Initialize);
GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);

我对此的理解可能仍然是错误的,但我已经花了很多时间试图弄清楚这一点,所以我希望有人能帮助我朝着正确的方向前进,因为我对如何进行有点迷茫.

有人可以帮助我了解如何让这小部分代码直接在 python 中工作吗?我只需要能够在一天结束时调用 NvAPI_GPU_GetUsages 函数。

谢谢。

【问题讨论】:

    标签: python ctypes nvidia


    【解决方案1】:

    为了查询gpu使用情况我 首先需要调用 NvAPI_Initialize 函数。

    实际上涉及两个初始化函数:一个来自静态库nvapi.lib,它尝试动态加载nvapi.dll,定位一些函数并调用动态链接库中的第二个初始化函数。从static库调用NvApi_Initialize的步骤大致如下:

    1. 检查 nvapi.dll 是否已经存在 加载,如果没有,加载它

    2. 使用 GetProcAddress 获取指向 nvapi_QueryInterface 来自 DLL 使用新获得的函数 查询带有 Id 的接口 0x150E828。这将是第二次 从初始化函数 动态库

    3. 调用获取的初始化函数。如果 功能成功(表示 通过返回值 0),获得两个 新函数指针通过 nvapi_QueryInterface,使用 ids 0x33C7358C(我们称之为 ENTER)和 0x593E8644(EXIT)。

    因此,如果您想保持纯 Python,则基本上必须使用 ctypes 复制这些步骤,这非常容易。完成后,在nvapi.dll中有一个清理函数,可以使用id0xD22BDD7E查询。如果你用完了这个库,记得调用这个函数。

    现在回到真正的问题:不幸的是,2010 年 12 月的 NVIDIA SDK 中没有函数 NvAPI_GPU_GetUsages。但是,NvAPI_GPU_GetDynamicPstatesInfoEx 允许您请求填充类型为 NV_GPU_DYNAMIC_PSTATES_INFO_EX 的结构数组,这反过来将包含给定域(即 GPU,帧缓冲区和视频引擎)。

    基本上,如果您想检索 GPU 使用信息,请将 NV_GPU_DYNAMIC_PSTATES_INFO_EX 结构体传输到 Python(请参阅 ctypes 文档中的 Structures and unions),创建一个至少包含 3 个结构体的数组并将该数组传递给 @987654328 @ 函数,您必须先从动态链接库中查询,使用 id 0x60DED2ED

    顺便说一句,这就是您在初始化期间查询的两个函数发挥作用的地方——这是一种锁定机制。虽然不是绝对必要的(即您可以在调用期间省略它),但我们鼓励您调用它们,即

    Enter()
    NvAPI_GPU_GetDynamicPstatesInfoEx(array_of_structs)
    Exit()
    

    您应该能够通过查看 NVAPI_GPU_UTILIZATION_DOMAIN_GPU 宏(或常量)来找到存储 GPU 使用信息在数组中的哪个位置,不幸的是,头文件中似乎没有包含声明开发工具包。不过,您可以通过将代码结果与显示 GPU 使用信息的 NVIDIA 系统工具进行比较来轻松验证这一点。

    希望对您有所帮助。

    【讨论】:

    • 感谢您的帮助。我遇到了麻烦,因为我认为我应该使用 ctypes WinDLL,但事实证明你必须使用 CDLL。使用 CDLL 后,我开始从 QueryInterface 获得有意义的结果。
    • 在哪里可以找到需要提供给 nvapi_QueryInterface 的幻数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多