/ / PerformanceCounter.NextValue () повертає постійне значення для завантаження процесора - c #, використання процесора, performancecounter

PerformanceCounter.NextValue () повертає константне значення для завантаження ЦП - c #, використання процесора, performanceancecounter

Я намагаюся прокрутити власну продуктивність системимонітору, щоб затримати виконання частини мого серверного коду у разі перевантаження (запуск деяких веб-служб під IIS). Перше, що я намагаюся вирішити, це перевантаження процесора.

Я знаю про PerformanceCounter проблеми з необхідністю ініціалізувати його з першого дзвінка на NextValue() (побачити це питання, серед інших), тому я реалізував дуже простий статичний клас, який кешує дані на секунду і лише фактично отримує доступ до PerformanceCounter об'єкт раз на секунду чи менше. Я знаю, що зараз це не безпечно для потоків, але я не переймаюся цим на етапі прототипування.

Отже, сказавши все це, ось мій поточний код:

public static class SystemPerformance
{
private static PerformanceCounter TotalProcessorTimeCounter =
new PerformanceCounter("Process", "% Processor Time", "_Total");
private static DateTime CacheRefreshed;
private static float CachedValue = 0f;
private const float MIN_DELTA_SECONDS = 1f;

public static float ReadCPU()
{
if ((DateTime.Now - CacheRefreshed).TotalSeconds > MIN_DELTA_SECONDS)
// Stale cache
return ReadFromCounter();

// Good cache
return CachedValue;
}

private static float ReadFromCounter()
{
CachedValue = TotalProcessorTimeCounter.NextValue();
CacheRefreshed = DateTime.Now;
return CachedValue;
}
}

... що все приємно і модно, поки я не виконаю. Я спробував запустити його на Windows 10 x64 VM з 4 ядрами, а в Windows 7 x64 залізо з 4 ядрами - і в обох випадках повернене значення коливається близько 400, незалежно від того, що я роблю.

Типові значення, які я отримую, знаходяться в діапазоні395–401, з випадковим пониженням до 365 або стрибком до 405. Значення, які я читав, жодним чином не співвідносяться з фактичним завантаженням процесора на будь-якій машині, яку я тестував, як це показано в Task Manager, Performance Monitor, або навіть звичайній сенс.

Методика тестування проста: SystemPerformance.ReadCPU() спрацьовує натисканням кнопки у простій формі Windows, а вихід відображається у текстовому полі в тому ж вигляді. Я натискаю цю кнопку, коли процесор майже не працює, і також натискаю її інші процеси роблять речі та завантажують процесор.

Що я роблю неправильно? Чи повинно це повернути використання процесора лише в потоках мого додатка? Чи я неправильно трактую дані?

Відповіді:

2 для відповіді № 1
   new PerformanceCounter("Process", "% Processor Time", "_Total");

Так, час процесора, зайнятий загальною кількістю процесів, включаючи підроблений "Процес очікування системи", який ви бачите в диспетчері завдань, завжди додаватиме до 400% на 4-х основній машині.

Вам, напевно, вам більше сподобається числозмінити "Процес" на "Процесор". Якщо ви хочете відповідати значенню, яке відображає диспетчер завдань, вам потрібно змінити "Обробити" на "Інформація про процесор". Нова категорія, яка намагається генерувати більш реалістичне число, яке "компенсується процесором з турбонаддувом, машинами з NUMA-вузлами та нижньою перф. Ви отримуєте з гіперпотоків. Ви хочете прочитати це повідомлення в блозі для азотно-зернистої.