/ / PerformanceCounter.NextValue () restituisce un valore costante per il carico della CPU - c #, cpu-use, performancecounter

PerformanceCounter.NextValue () restituisce un valore costante per il carico della CPU - c #, utilizzo della CPU, performancecounter

Sto cercando di migliorare le prestazioni del mio sistemamonitorare, al fine di ritardare l'esecuzione di parti del mio codice server in caso di sovraccarico (esecuzione di alcuni servizi Web in IIS). La prima cosa che sto cercando di risolvere è il sovraccarico della CPU.

So del PerformanceCounter problemi con la necessità di inizializzarlo con la prima chiamata a NextValue() (vedere questa domanda, tra gli altri), quindi ho implementato una classe statica molto semplice che memorizza i dati nella cache per un secondo e accede effettivamente al PerformanceCounter oggetto una volta al secondo o meno. So che al momento non è thread-safe, ma non mi preoccupo di quello nell'attuale fase di prototipazione.

Quindi, detto questo, ecco il mio codice attuale:

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

... che è tutto bello e dandy, fino a quando non lo eseguo. Ho provato a eseguirlo su una macchina virtuale Windows 10 x64 con 4 core e su Windows 7 x64 iron con 4 core - e in entrambi i casi, il valore restituito si aggira intorno ai 400, indipendentemente da ciò che faccio.

I valori tipici che ottengo sono nell'intervallo395–401, con il calo occasionale a 365 o un salto a 405. I valori che ho letto non sono in alcun modo correlati al carico effettivo della CPU su una delle macchine che ho testato, come mostrato da Task Manager, Performance Monitor o anzi comune senso.

La metodologia di test è semplice: SystemPerformance.ReadCPU() viene attivato premendo un pulsante in un semplice modulo di Windows e l'output viene mostrato in una casella di testo nello stesso modulo. Sto premendo quel pulsante mentre la CPU è quasi inattiva e lo premo anche mentre altri processi stanno facendo cose e caricando la CPU.

Che cosa sto facendo di sbagliato? Questo dovrebbe restituire l'utilizzo della CPU solo dai thread della mia applicazione? Sto interpretando male i dati?

risposte:

2 per risposta № 1
   new PerformanceCounter("Process", "% Processor Time", "_Total");

Sì, il tempo del processore impiegato dal _Totale numero di processi, incluso il falso "Processo di inattività del sistema" che vedi di nuovo in Task Manager, aggiungerà sempre fino al 400% su una macchina a 4 core.

Probabilmente ti piacerà il numero se lo faicambia "Processo" in "Processore". Se si desidera abbinare il valore visualizzato da Task Manager, è necessario modificare "Processo" in "Informazioni sul processore". Una nuova categoria che cerca di generare un numero più realistico che "è compensato per un processore con turbo boost, macchine con nodi NUMA e la perf inferiore che si ottiene dagli hyper-thread. Dovresti leggere questo post del blog per i grintosi.