使用PythoncTypes与nvapi接口(后续是演示代码)

使用PythoncTypes与nvapi接口(后续是演示代码),python,ctypes,nvidia,Python,Ctypes,Nvidia,这是我上一个问题的后续问题: 我正在发布另一个问题,因为我已经在上一个问题中选择了一个答案,现在这个问题已经改变了方向 使用python,我试图查询nvapi.dll以获取我的gpu使用值 这是您在C#中的操作方式(参考下文): 因为我只需要功能的一小部分,我真的不想换成使用另一种语言。我认为ctypes应该能够做到这一点。。。我就是不知道怎么做。我以前从未真正使用过Python ctypes 为了查询gpu的使用情况,我首先需要调用NvAPI_Initialize函数。还必须使用查询接口来引用

这是我上一个问题的后续问题:

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

使用python,我试图查询nvapi.dll以获取我的gpu使用值

这是您在C#中的操作方式(参考下文):

因为我只需要功能的一小部分,我真的不想换成使用另一种语言。我认为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;
    }
}
我对这一点的理解可能仍然是错误的,但我花了很多时间试图弄清楚这一点,所以我希望有人能帮助我朝着正确的方向前进,因为我对如何继续有点迷茫

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

谢谢

为了查询gpu的使用情况,我 首先需要打电话给 NvAPI_初始化函数

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

  • 检查nvapi.dll是否已经存在 已加载,如果未加载,请加载它

  • 使用GetProcAddress获取指向的指针
    nvapi\u查询接口
    来自DLL 使用新获得的函数 查询具有Id的接口 0x150E828。这将是第二次 来自 动态库

  • 调用获取的初始化函数。如果 功能成功(如图所示) 通过返回值0),获得两个 新函数指针通过
    nvapi\u查询接口
    ,使用 ids0x33C7358C(我们称之为ENTER)和0x593E8644(退出)

  • 因此,如果您想保持纯Python,基本上必须使用ctypes复制这些步骤,这将非常简单。完成后,nvapi.dll中有一个清理函数,您可以使用id0xD22BDD7E查询该函数。如果使用完库,请记住调用此函数

    现在来看真正的问题:不幸的是,在2010年12月的NVIDIA SDK中没有函数
    NvAPI\u GPU\u GetUsages
    。然而,
    NvAPI\u GPU\GetDynamicPstatesInfoEx
    允许您请求填充类型为
    NV\u GPU\u DYNAMIC\PSTATES\u INFO\u EX
    的结构数组,该数组反过来将包含给定域(即GPU、帧缓冲区和视频引擎)在最后一秒钟内的时间百分比利用率

    基本上,如果要检索GPU使用信息,可以将
    NV\GPU\u DYNAMIC\PSTATES\u INFO\u EX
    结构传输到Python(请参见ctypes文档中的内容),创建一个至少包含3个结构的数组,并将该数组传递给
    NvAPI\u GetDynamicPstatesInfoEx
    函数,您必须首先使用id0x60DED2ED从动态链接库中查询

    顺便说一句,这是两个函数在初始化过程中发挥作用的地方——这是一种锁定机制。虽然并非绝对必要(即,您可以在通话时忽略此项),但我们鼓励您致电他们,即

    Enter()
    NvAPI_GPU_GetDynamicPstatesInfoEx(array_of_structs)
    Exit()
    
    通过查看NVAPI\u GPU\u UTILIZATION\u DOMAIN\u GPU宏(或常量),您应该能够找到阵列中存储GPU使用信息的位置,不幸的是,SDK的头文件中似乎没有包含声明。不过,您可以通过将代码的结果与显示GPU使用信息的英伟达系统工具进行比较来轻松地验证这一点。
    希望能有所帮助。

    谢谢你的帮助。我在这方面遇到了麻烦,因为我认为我应该使用cTypesWindell,但事实证明,您必须使用CDLL。一旦我使用了CDLL,我就开始从QueryInterface中获得有意义的结果。我应该去哪里找到需要提供给nvapi_QueryInterface的神奇数字?
    Enter()
    NvAPI_GPU_GetDynamicPstatesInfoEx(array_of_structs)
    Exit()