Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a C# Program, I am trying to get the CPU usage percentage of the application but it always shows 100

Here is my code.

        PerformanceCounter cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";

        // will always start at 0
        dynamic firstValue = cpuCounter.NextValue();
        System.Threading.Thread.Sleep(1000);


        dynamic secondValue = cpuCounter.NextValue();
        return secondValue;

There are a lot of people here that are getting the problem that this returns zero, I however am getting 100 at all times, and I know for sure my software is not taking up that much CPU powrer. Any ideas as to what I can do to make this work correctly. To be clear I am trying to retrieve the processor usage from the application running this code not a separate one. Also I am running on a VM but that doesn't seem to matter. Any ideas?

like image 380
Alioo Avatar asked Jul 12 '12 20:07

Alioo


2 Answers

It helps to understand how a cpu works to figure out why this is happening. I'll simplify it a bit by talking about a cpu with only one core, the story doesn't change for one with multiple cores.

A cpu core can be in only two distinct states when it is not in a sleep mode. It is either executing code, running at full bore as fast as it can go executing instructions. Or it is not executing code because nothing needs to be done. In which case it is physically turned off. Which happens when it executes the HLT instruction. Halt, do nothing at all, consume no power.

There is only one way to revive the processor from the Halt state, an interrupt is needed. That's a physical pin on the chip, an electrical voltage on that pin jolts it back alive. That voltage is generated by an interrupt controller, another chip that takes requests from various parts of the machine to get the cpu to do something useful.

The most important source of that interrupt is a clock. It ticks at 0.0156 seconds, jolting the cpu back alive 64 times per second. Which activates a piece of code in the operating system that basically checks for two things. "Did something happen when I was asleep?". And "I haven't been asleep at all, time to do something else that's important too". Or in other words, it doesn't just jolt the cpu alive, it also interrupts it in what it was doing. Thus the name of the signal.

The clock is not the only source of interrupts, you've got other bits of hardware attached to the cpu. I/O devices. The important ones that any machine has are the disk controller, the optical drive controller, the network card, the mouse and the keyboard. And whatever else you see in the Device Manager applet. They are sub-systems with their own little processors that can take care of stuff. And tell the main cpu that they are done. So whatever thread on your machine was waiting for the result can resume executing with the supplied data.

The vast majority of the time, that personal computer you've got sitting next to you is not doing anything important. It is, say, waiting for you to read this answer. Something taken care of by the video adapter and the LCD monitor, the cpu doesn't have to help. You can see it in TaskMgr.exe, the cpu utilization is hovering around 0. You move the mouse, click on the scrollbar to read this (long) answer, then something happens. The mouse generates an interrupt, that gets passed through several layers of software and it ultimately tells the browser to scroll the view. That takes about a few milliseconds, give or take.

A few milliseconds of work, the cpu falls back asleep right after it. So when you ask the cpu, with the performance counter, "how much work have you done lately", it will say: "well, I spent a couple of milliseconds burning core and working my butt off updating your screen. But no, other than that I was sleeping on the pea"

So what matters is how often you ask. The boilerplate way is the one that Perfmon uses. Once a second it ask "what have you done". And the processor will say: "well, in the last second I've executed 20 milliseconds of useful work. I was dead the world the rest of the time, nothing useful to do". So task manager displays 2%.

Now lets do it your way. You ask for the perf counter value, then a nanosecond later you ask for it again. The processor will say: "well, I returned a performance counter value and tried to go back to sleep. Didn't work, the program kept running code and asked me the same thing!".

So the result is accurate, the processor was occupied with your requests, you didn't give it a chance to power down. Cpu utilization was 100%.

Solution: do it like Perfmon does. Ask once as second with a timer. Make it shorter and the number goes up and down faster. Make it too short and it will be 100%

like image 83
Hans Passant Avatar answered Sep 30 '22 03:09

Hans Passant


here is something that was done similar to what you may be trying to do

PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;

cpuCounter = new PerformanceCounter();

cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";

ramCounter = new PerformanceCounter("Memory", "Available MBytes");


public string getCurrentCpuUsage(){
            return cpuCounter.NextValue()+"%";
}

public string getAvailableRAM(){
            return ramCounter.NextValue()+"MB";
} 
like image 38
MethodMan Avatar answered Sep 30 '22 04:09

MethodMan