Справка по счетчику производительности C#, графический процессор Nvidia


Итак, я экспериментировал с классом performance counter в C# и имел большой успех, исследуя счетчики процессора и почти все, что я могу найти в мониторе производительности windows. Однако я не могу получить доступ к категории "NVIDIA GPU"...

Так, например, следующая строка кода-это то, как это обычно работает.

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

Этот код работает нормально, но категория GPU, которая появилась в мониторе производительности, так же как и категория процессора, недоступна С#. Следующая строка кода пытается получить к нему доступ.

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

Вместо этого он создает исключение" категория не существует"...

Вот как это выглядит изнутри монитора производительности

Введите описание изображения здесь

Категория явно существует, поэтому мой вопрос таков... как получить доступ к этому счетчику?
2 5

2 ответа:

Потратив на это шесть часов, я готов поделиться своими результатами. Для поиска этого отсутствующего счетчика производительности было использовано несколько методов тестирования.

1) Первым был очень простой поиск по ключевым словам. Это включало PerformaceCounterCategory, а также каждый отдельный экземпляр счетчика производительности, запущенный в моей системе (около 12 000 из них). Этот метод не нашел ничего связанного с GPU или NVIDIA,но работал безупречно для процессора.

2) следующим испытанием было: выполняется путем запуска GPU с очень специфическим % использованием, и был выполнен поиск, который оценивал каждый процентный счетчик производительности, работающий в узком диапазоне значений. Этот метод также не возвращал ничего, связанного с GPU,но снова работал безупречно для процессора.

Это приведет к одному выводу. действительно нет счетчика производительности для GPU, даже под ложным псевдонимом.


Решение:

Нигде не указано, что монитор производительности должен явно используйте счетчики производительности, и небольшой намек на это смотрел нам в лицо все это время. Переменная экземпляра в мониторе производительности была помечена как "NVAPI ID=256". API NVIDIA был разработан для обеспечения возможности мониторинга производительности оборудования NVIDIA. Хотя он может выполнять действия, аналогичные счетчикам производительности, он не использует одни и те же типы данных для выполнения своей задачи. Теперь у нас есть доказательства того, что монитор производительности использовал NVAPI для сбора данных информация вместо использования счетчика производительности. Это было очень обманчиво, потому что каждая другая запись соответствует счетчику. Таким образом, мы можем заключить, что единственный правильный способ доступа к этим переменным-через NVAPI.

Я смог сделать это успешно, сначала загрузив NVAPI с веб-сайта NVIDIA здесь.

Далее я использовал некоторый пример кода, найденный здесь у блоггера, который использует исходный код Open Hardware Monitor, и здесь из другого поста на этом сайте.

Код написан на C++, но после перемещения некоторых библиотек и создания нескольких .dll-это все прекрасно переносится на C#.

Вот картина результата. Спасибо всем за вашу помощь и поддержку!

Введите описание изображения здесь

Делаем а PerformanceCounterCategory.GetCategories() вы получите список всех категорий в вашей системе, как только найдете правильную катагорию, которую вы можете использовать PerformanceCounterCategory.GetCounters() перечислит все счетчики в этой катагории, чтобы вы могли получить правильное имя.

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();
}