/ / PerformanceCounter.NextValue () връща постоянна стойност за натоварването на CPU - c #, cpu-usage, performancecounter

PerformanceCounter.NextValue () връща постоянна стойност за зареждане на процесора - c #, CPU-usage, performancecounter

Опитвам се да превъртя собствената си производителност в систематамонитор, за да забави изпълнението на части от сървърния код в случай на претоварване (стартиране на някои уеб услуги по 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");

Да, процесорното време, взето от _Total броя на процесите, включително фалшивия "System Idle Process", който виждате в Task Manager, винаги ще добави до 400% на 4-ядрена машина.

Вероятно ще ви хареса по-добрият брой, ако виепроменете "Процес" на "Процесор". Ако искате да съответствате на стойността, която се показва на диспечера на задачите, трябва да промените "Процес" на "Информация за процесора". Нова категория, която се опитва да генерира по-реалистично число, което е компенсирано за процесор с турбо-тласък, машини с NUMA възли и по-нисък perf от хипер-нишки. тази публикация в блога за нищожните.