C#性能计数器帮助,Nvidia GPU

8

我一直在尝试使用C#中的Performance Counter类进行实验,并且在探测CPU计数器和几乎所有我能在Windows性能监视器中找到的内容方面取得了巨大成功。然而,我无法访问“NVIDIA GPU”类别...

例如,以下代码行通常是如何工作的。

PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");

那段代码运行良好,但是出现在性能监视器中的GPU类别(就像处理器类别一样)无法被C#访问。下面这行代码试图去访问它。

PerformanceCounter gpuCounter = new PerformanceCounter("NVIDIA GPU", "% GPU Usage","#0 Quadro K1100M(id=1, NVAPI ID=256)");

相反,它会抛出一个“类别不存在”的异常...

从性能监视器内部看,它看起来像这样

enter image description here

类别显然存在,所以我的问题是...我如何访问此计数器?


我已经研究了Nvidia PerfKit,但是文档并不是很有帮助,所以它可能有效,但是那里有太多的信息,而且缺乏足够的运行时示例。 - Alex E
不确定这是否重要,但我注意到您提供的类别名称与屏幕截图中显示的字符串不匹配。您的代码在K1100M和开括号之间没有空格。可能并不重要,但这是我注意到的事情。 - Michael A. Allen
2个回答

17

经过六个小时的研究,我准备分享一下我的结果。有几种测试方法用于寻找这个缺失的性能计数器。

1)第一种方法是搜索关键词。这包括PerformaceCounterCategory以及在我的系统上运行的每个性能计数器实例(大约12,000个)。这种方法没有找到任何与GPU或NVIDIA相关的内容,但对于CPU来说完全有效。

2)下一个测试是通过以非常特定的%使用率运行GPU,并进行了一个搜索,以评估在一系列值的狭窄范围内运行的每个百分比性能计数器。这种方法也没有返回任何与GPU相关的内容,但对于CPU再次完全有效。

这导致了一个结论。GPU真的没有性能计数器,甚至没有虚假别名。


解决方案:

并没有明确规定性能监视器必须明确使用性能计数器,而且小小的提示一直在我们面前。性能监视器中的实例变量标记为“NVAPI ID = 256”。NVIDIA API旨在允许对NVIDIA硬件进行性能监控。尽管它可以执行类似于性能计数器的操作,但它不使用相同的数据类型来执行其任务。我们现在有证据表明,性能监视器使用NVAPI收集信息,而不是使用性能计数器。这非常具有误导性,因为每个其他条目都对应一个计数器。因此,访问这些变量的唯一正确方法是通过NVAPI。

我成功地完成了这项工作,首先从NVIDIA网站https://developer.nvidia.com/nvapi下载了NVAPI。

接下来,我使用了在这里找到的一些示例代码,该博主正在使用Open Hardware Monitor源代码,并使用了这里另一篇帖子上的代码。

这段代码是用C++编写的,但是在移动了一些库并制作了几个.dll文件后,一切都很容易地移植到了C#。

以下是输出结果的图片。感谢大家的帮助和支持!

在此输入图片描述


谢谢您发布更新,我也为此感到困惑。 - Scott Chamberlain

2
执行 PerformanceCounterCategory.GetCategories() 会列出系统上所有类别的列表,一旦找到正确的类别,您可以使用 PerformanceCounterCategory.GetCounters() 列出该类别中的所有计数器,以便获取正确的名称。请注意保留HTML标记。
var cat = new PerformanceCounterCategory("Whatever the correct category name is");
var counters = cat.GetCounters();

更新:

尝试这个来搜索它

static void Main(string[] args)
{
    var counters = PerformanceCounterCategory.GetCategories()
        .SelectMany(x=>x.GetCounters("")).Where(x => x.CounterName.Contains("GPU"));

    foreach (var counter in counters)
    {
        Console.WriteLine("{0} - {1}", counter.CategoryName, counter.CounterName);
    }
    Console.ReadLine();
}

1
我检查了我的性能计数器,但在我的机器上没有那个类别,否则我也会包括实际名称是什么。 - Scott Chamberlain
1
同样地,如上所述,该类别不存在。PerformanceCounterCategory.GetCategories() 不返回任何与 GPU 或 NVIDIA 相关的内容。因此,问题仍然存在,我如何访问在 PerfMon 中找到但不公开可见的此类别。 - Alex E
这真的没有意义,没有办法做一个私有计数器,它必须存在,但是在你不期望的名称下。也许是某种神秘的缩写?我真的希望我能提供更多帮助,但正如我所说,我的“NVIDIA GPU”菜单中没有“添加计数器”,所以我有点盲目。 - Scott Chamberlain
@AlexE,请尝试我的更新中的搜索代码,你能从中得到任何有用的东西吗? - Scott Chamberlain
@AlexE 另外一件你可以尝试的事情,从命令行执行 typeperf -q -o "C:\Temp\counters.txt",然后在生成的 txt 文件中搜索 GPU - Scott Chamberlain
非常感谢您的帮助。我使用了类似的策略来追踪问题,并在下面发布了我的结果。 - Alex E

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