% Processor Utility counter returning over 100% - c#

I'm working in an application that needs to monitor CPU usage on Windows 10. I'm using PerformanceCounter and counter % Processor Utility. When the CPU usage in Windows Task Manager gets 100%, PerformanceCounter returning more than 100% (like 120, 170%).
PerformanceCounter cpuUsage = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total", true);
Searching i've found that sometimes it's normal processor utility return more than 100%. But task manager don't show values higher than 100%.
I want to know if is there a way to "convert" processor utility return into a 100% scale? what is the highest value that the processor utility can achieve? is the maximum processor utility return limit associated with the number of cpu cores?

Related

C#: how to limit or reduce processor consumption of external process

I run an external process inside a C# program with the API/method:
Process p = Process.Start(exefilename);
I want to decrease the CPU consumption of the process "exefilename" and I tried to change the priority in this way:
p.PriorityClass = ProcessPriorityClass.Idle;
but I did not get any result. The processor consumption is the same.
In which way can I reduce the CPU consumption?
First are you sure that this process is what consuming the CPU?
secondly if you have its source code, you should check which portion of it is consuming the CPU (IO, DB calls) and so on.

C# measure process CPU usage on multiple processors windows server

I tried to monitor a windows service CPU usage on a windows server with 24 processors. I used
_cpuCounter = new PerformanceCounter(
"Process", "% Processor Time", Process.GetCurrentProcess().ProcessName, true);
_cpuCounter.NextValue()/100 //most time, it is more than 100%, which is not correct.
But it does not give me the correct Process CPU usage.
The results are not incorrect. It's just that NextValue() will return values greater than 100 when your process uses more than one CPU and the individual values add up to "more" than 100%.
For instance, if your process uses 50% of CPU0 and 60% of CPU1 the result will be 110% usage of all potentially available CPU cycles across all CPUs/cores (which is expressed as 200% for dual core processors).
If you want a value taking the number of processors into acount (i.e. mapping 110 to 55 on a dual core machine) try dividing the retrieved value by the number of processors instead:
_cpuCounter.NextValue() / Environment.ProcessorCount

How to measure disk's "average response time" as in Windows 8.1 Task manager

If you open Windows 8.1 Task Manager, choose "More details", "Performance" tab, and "Disk 0" item, you'll see "Average response time" value expressed in milliseconds.
How to get this value using PerformanceCounter class?
Here are counters I use:
static PerformanceCounterCategory PhysicalDiskCategory = new PerformanceCounterCategory("PhysicalDisk");
static List<string> PhysicalDisks = new List<string>(PhysicalDiskCategory.GetInstanceNames());
static string Disk0Instance = PhysicalDisks.FirstOrDefault(i => i.StartsWith("0"));
static PerformanceCounter DiskTimeCounter = new PerformanceCounter("PhysicalDisk", "% Disk Time", Disk0Instance);
static PerformanceCounter DiskTransferCounter = new PerformanceCounter("PhysicalDisk", "Disk Bytes/sec", Disk0Instance);
static PerformanceCounter DiskAvgSecTransferCounter = new PerformanceCounter("PhysicalDisk", "Avg. Disk sec/Transfer", Disk0Instance);
static PerformanceCounter DiskAvgQueueLengthCounter = new PerformanceCounter("PhysicalDisk", "Avg. Disk Queue Length", Disk0Instance);
None of them gives me the value, however "Avg. Disk Queue Length" seems to be closely related to "Average response time". It seems reasonable - the more disk latency - the longer disk queue gets. But how does Task Manager get it? Is it calculated from more than one counter?
BTW, How to tell the difference between low impact background disk operations (run Windows Defender full scan to observe this) from high impact ones (during Windows startup)?
Shortly after you get to the Windows desktop the computer is very unresponsive, next to useless, for a couple of minutes (or seconds if you have fast SSD). This is related to disk time. When you wait until disk time drops below 50% - system is perfectly responsive.
However it's not the case when disk time over 90% is caused by Windows Defender or other background tasks. It doesn't affect system responsiveness. Hibernate and restore system. You'll notice disk time over 90% for at least a minute (up to 5 minutes on mine). But there is no problem with system responsiveness. Visual Studio starts almost immediately. There are no lags on opening big projects.
I figured out that shortly after reboot "Average response time" is huge compared to values measured while AV scan. This could be exactly it - a way to measure REAL system responsiveness. But how do they get it? How to get it in .NET app?

ParallelQuery core balancing

I have 200,000 tasks that will run in parallel for speed gains. I'm using ParallelEnumerable.Range(0, 200000).Sum( a => /*do_something*/ ).
as the task counter goes from 0 to 200,000 the required number of iterations decreases. The task with a=0 requires most number of iterations, while tasks with a>100,000 finish with one or no iteration.
due to this, my quad-core machine isn't reaching max cpu utilization peak as the tasks progress. It seems like the workload is distributed to all 4 cores at start, and some cores go idle earlier as their portion was mainly tasks with high as. cpu utilization starts with 100%, but drops gradually to 75~50~25%. How can I achieve full cpu utilization from start to end?
very simple self-answer : replacing ParallelEnumerable.Range(0, 200000) with Enumerable.Range(...).AsParallel() was enough to solve this problem. The it seems that the workload is distributed dynamically in Enumerable.Range(...).AsParallel().

How to find the cpu usage of a particular process at that moment of time in Windows

Is it possible to know the CPU usage of a running/idle process programatically (in any language) in Windows?
If you don't care on support old Windows versions (earlier than Windows XP SP1) you could use GetSystemTimes Win32 API function.
Otherwise you have to use Performance Counters.
in C# you can do following:
private PerformanceCounter cpuCounter = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName);
cpuCounter.NextValue(); // it will give you cpu usage
you should refer here for details.

Categories