/ / PerformanceCounter.NextValue () zwraca stałą wartość obciążenia procesora - c #, użycie procesora, performancecounter

PerformanceCounter.NextValue () zwraca stałą wartość dla obciążenia procesora - c #, cpu-usage, performancecounter

Próbuję zwiększyć wydajność własnego systemumonitorować, aby opóźnić wykonanie części mojego kodu serwera w przypadku przeciążenia (uruchomienie niektórych usług internetowych w ramach IIS). Pierwszą rzeczą, którą próbuję rozwiązać, jest przeciążenie procesora.

Wiem o tym PerformanceCounter problemy z inicjowaniem go przy pierwszym połączeniu z NextValue() (widzieć to pytanie, między innymi), więc zaimplementowałem bardzo prostą klasę statyczną, która buforuje dane przez sekundę i faktycznie uzyskuje dostęp do PerformanceCounter obiekt raz na sekundę lub krócej. Wiem, że obecnie nie jest bezpieczny wątkowo, ale nie martwię się tym w obecnej fazie prototypowania.

Powiedziawszy to wszystko, oto mój obecny kod:

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

... co jest miłe i eleganckie, dopóki go nie wykonam. Próbowałem uruchomić go na maszynie wirtualnej z systemem Windows 10 x64 z 4 rdzeniami, a na żelazku z systemem Windows 7 x64 z 4 rdzeniami - w obu przypadkach zwracana wartość oscyluje wokół 400, bez względu na to, co robię.

Typowe wartości, które otrzymuję, mieszczą się w zakresie395–401, z okazjonalnym spadkiem do 365 lub skokiem do 405. Wartości, które czytam, nie są w żaden sposób skorelowane z faktycznym obciążeniem procesora na żadnym z testowanych przeze mnie komputerów, jak pokazuje Menedżer zadań, Monitor wydajności, a nawet wspólne sens.

Metodologia testowania jest prosta: SystemPerformance.ReadCPU() jest uruchamiany przez naciśnięcie przycisku w prostej formie systemu Windows, a dane wyjściowe są wyświetlane w polu tekstowym w tej samej formie. Naciskam ten przycisk, gdy procesor jest quasi-bezczynny, a także naciskam go, gdy inne procesy robią rzeczy i ładują procesor.

Co ja robię źle? Czy to ma zwracać użycie procesora tylko przez wątki mojej aplikacji? Czy źle interpretuję dane?

Odpowiedzi:

2 dla odpowiedzi № 1
   new PerformanceCounter("Process", "% Processor Time", "_Total");

Tak, czas procesora zajęty przez _ Łączną liczbę procesów, w tym fałszywy „System bezczynności procesu”, który widzisz w Menedżerze zadań, zawsze będzie sumował się do 400% na czterordzeniowej maszynie.

Prawdopodobnie polubisz ten numer, jeśli takzmień „Process” na „Processor”. Jeśli chcesz dopasować wartość wyświetlaną przez Menedżera zadań, musisz zmienić „Proces” na „Informacje o procesorze”. Nowa kategoria, która próbuje wygenerować bardziej realistyczną liczbę, która jest kompensowana dla procesora z doładowaniem turbo, maszyn z węzłami NUMA i niższej wydajności uzyskiwanej z hiperwątków. Będziesz chciał przeczytać ten wpis na blogu za drobiazg.